[React Native]Push Notification

지리·2023년 6월 8일

Push Notification

참고

Installation


Device State


  • Foreground 앱이 열려있는경우
  • Background 앱이 열려있지만 백그라운드에 있는경우
  • Quit 디바이스가 잠겨있거나 앱이 실행되고 있지 않은 상태

Message Handlers

Foreground - onMessage
Background, Quit - setBackgroundMessageHandler

android와 ios에서 background나 quit상태일때 data만 보내질경우 메세지를 무시해버린다.

Subscribing to message


  • onMessage : 앱이 실행되는 중이거나 백그라운드에 있을경우
  • setBackgroundMessageHandler : 앱이 실행되어 있지 않은경우
import messaging from '@react-native-firebase/messaging';

// Note that an async function or a function that returns a Promise 
// is required for both subscribers.
async function onMessageReceived(message) {
  // Do something
}

messaging().onMessage(onMessageReceived);
messaging().setBackgroundMessageHandler(onMessageReceived);

SendingMessage


메세지를 보내기 위해서 메세지 토큰 이 필요하다. 이 토큰은 각 디바이스의 고유한 토큰으로 데이터베이스에 저장하고 FCM에 메세지가 보내질때 디바이스를 특정할 수 있음.

Create Token

It is recommended you fetch and update the token each time the application boots in-case it has changed.

import messaging from '@react-native-firebase/messaging';

async function onAppBootstrap() {
  // Register the device with FCM
  await messaging().registerDeviceForRemoteMessages();

  // Get the token
  const token = await messaging().getToken();

  // Save the token
  await postToApi('/users/1234/tokens', { token });
}

IOS
IOS는 유저에게 허가를 받지 않으면 notification을 포함한 payload를 막기때문에 requestPermission로 유저의 허가를 요청하는 native permission dialog로 허가를 받는다.
IOS Permissions

import messaging from '@react-native-firebase/messaging';

async function requestUserPermission() {
  const authStatus = await messaging().requestPermission();
  const enabled =
    authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
    authStatus === messaging.AuthorizationStatus.PROVISIONAL;

  if (enabled) {
    console.log('Authorization status:', authStatus);
  }
}

norifiee를 이용할 경우

import notifee, { AuthorizationStatus } from '@notifee/react-native';

async function requestUserPermission() {
  const settings = await notifee.requestPermission();

  if (settings.authorizationStatus >= AuthorizationStatus.AUTHORIZED) {
    console.log('Permission settings:', settings);
  } else {
    console.log('User declined permissions');
  }
}

자세한 IOS Permision Setting

setting을 확안하고 싶다면

  const settings = await notifee.requestPermission();

Categories / Grouping

ios의 경우 Category를 android는 Group을 만들 수 있다

ios
action이란 알림창에서 바로 취할수 있는 버튼을 만들어주는데 버튼을 눌렀을경우 onBackgroundEvent에서 pressAction에 action의 id 값이 들어간다.


async function setCategories() {
  await notifee.setNotificationCategories([
    {
      id: 'message',
      actions: [
        {
          id: 'mark-as-read',
          title: 'Mark as read',
        },
      ],
    },
  ]);
}

notifee.displayNotification({
  title: 'New post from John',
  body: 'Hey everyone! Check out my new blog post on my website.',
  ios: {
    categoryId: 'message',
  },
});
import notifee, { EventType } from '@notifee/react-native';

notifee.onBackgroundEvent(async ({ type, detail }) => {
  if (type === EventType.ACTION_PRESS && detail.pressAction.id === 'mark-as-read') {
    console.log('User pressed the "Mark as read" action.');
  }
});

Handling Interaction


notifee의 backgroundHandler가 동작 안되서 대체

  • getInitialNotification: When the application is opened from a quit state.
  • onNotificationOpenedApp: When the application is running, but in the background.
useEffect(() => {
    // Assume a message-notification contains a "type" property in the data payload of the screen to open

    messaging().onNotificationOpenedApp(remoteMessage => {
      console.log(
        'Notification caused app to open from background state:',
        remoteMessage.notification,
      );
      navigation.navigate(remoteMessage.data.type);
    });

    // Check whether an initial notification is available
    messaging()
      .getInitialNotification()
      .then(remoteMessage => {
        if (remoteMessage) {
          console.log(
            'Notification caused app to open from quit state:',
            remoteMessage.notification,
          );
          setInitialRoute(remoteMessage.data.type); // e.g. "Settings"
        }
        setLoading(false);
      });
  }, []);

Issue


ios에서 setBackgroundMessageHandler가 작동이 안됨. android에서는 제대로 동작하는데 ios에서만 작동하지 않았다.

해결
일단 나는 postman으로 간단하게 테스트 하기 위해 Firebase Cloud Messaging API(V1)을 이용하지 않고 기존에 있던 Cloud Messaging API를 이용했다.
content-available값이 없을 경우 ios에서 setBackgroundMessageHandler가 동작하지 않음
참고

--수정버전--

header
Authorization : key=firebase서버키
Content-Type : application/json

body

{
	"to":"기기의 토큰값",
	"notification":{
		"title" : "노티 타이틀",
		"body" : "노티 바디"
	},
	"data" : {
		"title" : "데이터 타이틀",
		"body" : "데이터 바디"
	},
	"content_available":true
}
  • 알림관련
    알림표시는 언제 꺼져야 하는지 앱에 들어가고 나서? 아니면 알림창을 보고 나서?
    background에 열려있는경우에
profile
공부한것들, 경험한 것들을 기록하려 노력합니다✨

0개의 댓글