Push Notification 설치 및 적용

부가 설명
Tags
Push Noti
config
모바일 기기로 알림메세지를 보내는 것을 말한다.

참고링크


파이어베이스에 앱 등록

파이어베이스 앱 등록 (안드로이드)
파이어베이스 앱 등록(ios)

필요 패키지 설치 (공통)

# 패키지 설치 $ npm install --save react-native-push-notification $ npm install --save @react-native-firebase/app@11.5.0 $ npm install --save @react-native-firebase/messaging@11.5.0 $ npm install --save @react-native-community/push-notification-ios $ npm install --save @react-native-firebase/iid@11.5.0 or $ yarn add react-native-push-notification $ yarn add @react-native-firebase/app@11.5.0 $ yarn add @react-native-firebase/messaging@11.5.0 $ yarn add @react-native-community/push-notification-ios $ yarn add @react-native-firebase/iid@11.5.0 # ios 링킹 $ npx pod-install
 

앱별 네이티브 추가 환경설정

1) android

gradle 설정 등은 firebase에 앱 등록할 때 다 했으므로 아래 추가 코드들만 추가하면 됨.
안드로이드 Push Notification 셋팅

android/app/src/main/AndroidManifest.xml 편집

  • 권한 설정 추가
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  • 아래 코드를 <application> 태그 사이에 추가
<meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground" android:value="false"/> <!-- Change the resource name to your App's accent color - or any other color you want --> <meta-data android:name="com.dieam.reactnativepushnotification.notification_color" android:resource="@color/white"/> <!-- or @android:color/{name} to use a standard color --> <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" /> <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" /> <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.QUICKBOOT_POWERON" /> <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/> </intent-filter> </receiver> <service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService" android:exported="false" > <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
 

android/app/src/main/res/values/colors.xml 파일 생성

notification_color meta-data에 built in Android color를 쓰고 있지 않다면 해당 파일 생성.
코드 삽입
<resources> <color name="white">#FFF</color> </resources>
notion image

android 추가 고려사항

  • Scheduled Notifications(예약 알림) 사용 하려면, AndroidManifest.xml 수동 업데이트 필요
  • 뒤에서 다시 다룸
 
 
설정 끝!
 
 

2) ios - 무료 애플 계정은 안됨. 개발자 계정 필요

ios에선 컴포넌트가 PushNotificationIOS를 의존하므로 추가 설치 필요.
PushNotificationIOS 설치 정리

설치 (RN ≥ 0.60 기준)

# 패키지 설치 $ yarn add @react-native-community/push-notification-ios # 오토 링킹까지 $ npx pod-install

Capabilities 추가

  1. 프로젝트명/ios 폴더로 이동 후 .xcworkspace 파일로 네이티브 프로젝트를 연다.
  1. Signing & Capabilities 탭으로 이동 후 2개의 역량을 추가한다.
      • Background Mode, 그리고 Remote Notifications에 체크한다.
      • Push Notifications (안나옴) ← 개발자 계정 있어야 사용 가능
      notion image
       
  1. AppDelegate 편집
    1. notification을 지원하고 이벤트를 등록하려면 편집 필요.

      AppDelegate.h 수정

      • 최상단에 import문 추가하고, (최상단에 필수!!!)
        • #import <UserNotifications/UNUserNotificationCenter.h>
      • AppDelegate에 UNUserNotificationCenterDelegate 프로토콜 추가
      notion image

      AppDelegate.m 수정

      • 최상단에 import문 추가하고 (최상단에 필수!!!)
        • #import <UserNotifications/UserNotifications.h> #import <RNCPushNotificationIOS.h>
      • @implementation에 다음 코드 추가
        • /* ------ Push Notification Settings ------ */ // Required for the register event. - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; } // Required for the notification event. You must call the completion handler after handling the remote notification. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; } // Required for the registrationError event. - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error]; } // Required for localNotification event - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler { [RNCPushNotificationIOS didReceiveNotificationResponse:response]; } //Called when a notification is delivered to a foreground app. -(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge); } /* ------------------------------------ */
           
      • application:didFinishLaunchingWithOptions 구현부에 코드 추가
        • ... // Define UNUserNotificationCenter UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = self; return YES; }
           
  1. Migrating from the core react-native module
    1. 이 모듈은 React Native Core에서 PushNotificationIOS가 분리 되었을 때 생성된 모듈이다.
      즉 import from 'react-native' 로는 PushNotificationIOS 컴포넌트를 쓸 수 없다.
      // 이 코드를 import {PushNotificationIOS} from 'react-native'; // 이렇게 변경 import PushNotificationIOS from '@react-native-community/push-notification-ios';
 
 

React Native 코드 설정

공식문서에도 나와있지만 PushNotification.configure() 함수를 App.js를 포함한 어떤 컴포넌트 내부에서도 사용하지 말라고 했음. ( notification 핸들러 동작 안함. 왜? 컴포넌트가 로드가 안된 상황에서 알림 받으면 아무것도 못하므로 )
⇒ 일반적으로 index.js 내부에서 사용함.

index.js 예시

import { AppRegistry } from 'react-native'; import messaging from '@react-native-firebase/messaging'; import App from './App'; import { name as appName } from './app.json'; /* ------------ push notification 받기 위한 셋팅 (백그라운드) ------------- */ import Firebase from '@react-native-firebase/app' import PushNotification from "react-native-push-notification"; import PushNotificationIOS from "@react-native-community/push-notification-ios"; Firebase.initializeApp(this); // Must be outside of any component LifeCycle (such as `componentDidMount`). PushNotification.configure({ // (optional) Called when Token is generated (iOS and Android) onRegister: function (token) { console.log("TOKEN:", token); }, // (required) Called when a remote is received or opened, or local notification is opened onNotification: function (notification) { console.log("NOTIFICATION:", notification); // process the notification // (required) Called when a remote is received or opened, or local notification is opened notification.finish(PushNotificationIOS.FetchResult.NoData); }, // (optional) Called when Registered Action is pressed and invokeApp is false, if true onNotification will be called (Android) onAction: function (notification) { console.log("ACTION:", notification.action); console.log("NOTIFICATION:", notification); // process the action }, // (optional) Called when the user fails to register for remote notifications. Typically occurs when APNS is having issues, or the device is a simulator. (iOS) onRegistrationError: function (err) { console.error(err.message, err); }, // IOS ONLY (optional): default: all - Permissions to register. permissions: { alert: true, badge: true, sound: true, }, // Should the initial notification be popped automatically // default: true popInitialNotification: true, /** * (optional) default: true * - Specified if permissions (ios) and token (android and ios) will requested or not, * - if not, you must call PushNotificationsHandler.requestPermissions() later * - if you are not using remote notification or do not have Firebase installed, use this: * requestPermissions: Platform.OS === 'ios' */ requestPermissions: true, }); /* --------------------------------------------------------- */ AppRegistry.registerComponent(appName, () => App);
 

Firebase 웹 콘솔에서 Push Noti 테스트

Firebase 웹 콘솔로 Push Noti 테스트

1) Cloud Messaging 시작

  • Firebase Console로 이동 → 내 프로젝트 선택 → Cloud Messaging 클릭
notion image
 

2) Push 메세지 작성

  • 처음이라면 아래 그림이 나오고,
  • 아니라면 알림 관련 대시보드 창이 나옴.
notion image
notion image
 

3) Push 메세지 정보 입력

notion image
 

4) Push 메세지 전송

notion image
 

5) Push 메세지 관련 대시보드

notion image
 

6) 앱에서 수신확인

  • 현재 백그라운드 상에서는 아래와 같이 동작하고,
  • 포그라운드 상이라면 콘솔로만 찍도록 해놨다.
notion image
 
 

Firebase Admin SDK 사용해서 Push Noti 보내기

node 서버 코드 작성

node.js (서버)

패키지 설치

$ npm install firebase-admin --save or $ yarn add firebase-admin
 

Firebase Admin SDK 키 발급

  • json 파일로 다운로드됨.
notion image
notion image
 

Admin SDK 구성 스니펫

  • 아래 코드를 복사해서 admin sdk 사용 가능.
notion image
var admin = require("firebase-admin"); //admin sdk 키가 담긴 json 파일 경로로 수정 필요 var serviceAccount = require("path/to/serviceAccountKey.json"); admin.initializeApp({ credential: admin.credential.cert(serviceAccount) });
 

푸시 알림 구성, 알림 받을 디바이스 설정

const registrationToken= "<푸시 알림 전달할 디바이스의 토큰값>"; const payload = { notification:{ title: "제목 테스트", body: "바디 테스트" } };
 

푸시 알림 보내기

admin.messaging().sendToDevice(registrationToken, payload) .then( (response) => { console.log("Successfully sent message:", response); }) .catch( (error) => { console.log("Error sending message:", error); })
 

서버 코드 예시

const { response } = require('express'); const express = require('express'); const router = express.Router(); var admin = require("firebase-admin"); var serviceAccount = require("/Users/night-ohl/Desktop/nodeEnv/mobile90-aa3b8-firebase-adminsdk-3lof4-e7501ecadc.json"); admin.initializeApp({ credential: admin.credential.cert(serviceAccount) }); router.get('/personal', (req, res, next)=>{ const registrationToken= "eg3bA1gLTkKBY1cAiqUda9:APA91bECfVx_e4SmbEPcJqix1e3OFrwhjqlmTO9_zKeNYtMorZEfoVBU6Pvea56mznzjmGT9Zic-cKoazAlQgOv0Vsodlq-ZthKB3Sw8l0fExSkCAJWh-e86rLMXbZkhdr0deA0pfN9t"; const payload = { notification:{ title: "제목 테스트", body: "바디 테스트" } }; admin.messaging().sendToDevice(registrationToken, payload) .then( (response) => { console.log("Successfully sent message:", response); }) .catch( (error) => { console.log("Error sending message:", error); }) res.send("Push-Noti 테스트 완료"); }) module.exports = router;
notion image
 

클라이언트 결과

notion image
notion image