このプラグイン react-native-Push-notifications を使用して、react nativeでプッシュ通知を実装しようとしています。私が成功するのは、アプリの実行中(フォアグラウンド)に通知を取得することですが、私がやろうとしているのは、アプリが実行されずに閉じられた(バックグラウンド)ときに通知を取得することです。
私のコード
componentDidMount() {
this.initEventPushNotification()
this.initPushNotification()
}
initEventPushNotification() {
AppState.addEventListener('change', (state) => {
console.log(state)
if (state === 'background') {
PushNotification.popInitialNotification((notification) => {
if (notification) {
this.onNotification(notification);
}
});
PushNotification.setApplicationIconBadgeNumber(0);
}
if (state === 'active') {
PushNotification.popInitialNotification((notification) => {
if (notification) {
this.onNotification(notification);
}
})
}
});
}
initPushNotification() {
console.log('init')
PushNotification.configure({
// (optional) Called when Token is generated (iOS and Android)
onRegister: function (token) {
AppStore.setFCMToken(token.token)
FirebaseService.setTokenData(token.token)
},
// (required) Called when a remote or local notification is opened or received
onNotification: function (notification) {
if (!notification.userInteraction) {
PushNotification.setApplicationIconBadgeNumber(0);
}
if (notification) {
console.log(notification)
PushNotification.localNotification({
/* Android Only Properties */
id: '0', // (optional) Valid unique 32 bit integer specified as string. default: Autogenerated Unique ID
ticker: "My Notification Ticker", // (optional)
autoCancel: true, // (optional) default: true
largeIcon: "ic_launcher", // (optional) default: "ic_launcher"
smallIcon: "ic_notification", // (optional) default: "ic_notification" with fallback for "ic_launcher"
bigText: "My big text that will be shown when notification is expanded", // (optional) default: "message" prop
subText: "This is a subText", // (optional) default: none
color: "red", // (optional) default: system default
vibrate: true, // (optional) default: true
vibration: 300, // vibration length in milliseconds, ignored if vibrate=false, default: 1000
tag: 'some_tag', // (optional) add tag to message
group: "group", // (optional) add group to message
ongoing: false, // (optional) set whether this is an "ongoing" notification
/* iOS only properties */
message: "My Notification Message", // (required)
playSound: false, // (optional) default: true
soundName: 'default', // (optional) Sound to play when the notification is shown. Value of 'default' plays the default sound. It can be set to a custom sound such as 'Android.resource://com.xyz/raw/my_sound'. It will look for the 'my_sound' audio file in 'res/raw' directory and play it. default: 'default' (default sound is played)
number: '10', // (optional) Valid 32 bit integer specified as string. default: none (Cannot be zero)
repeatType: 'day', // (Android only) Repeating interval. Could be one of `week`, `day`, `hour`, `minute, `time`. If specified as time, it should be accompanied by one more parameter 'repeatTime` which should the number of milliseconds between each interval
actions: '["Yes", "No"]', // (Android only) See the doc for notification actions to know more
});
}
// process the notification
// required on iOS only (see fetchCompletionHandler docs: https://facebook.github.io/react-native/docs/pushnotificationios.html)
// notification.finish(PushNotificationIOS.FetchResult.NoData);
},
// Android ONLY: GCM Sender ID (optional - not required for local notifications, but is need to receive remote Push notifications)
senderID: "XXXXXXXXXX1", // my sender ID
// 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
*/
requestPermissions: true,
});
}
Firebase関数を使用して通知を送信しています
export const sendNotificationTest = functions.https
.onRequest(async (req, res) => {
try {
const { token } = req.body;
let tokens = "coeC4T6tmeU:APA91bGEQs4MRQXq4C09SKpyK2Oxz7gIKS-QdoGGKeCcxQj2CXGpCD7qe763WnFVgQRer81iZGscASVq-QP7_I81xtCM9vfiPitQJ4P6HFSH3QiGQQljiLPBixsVcCtbDNCZX4z4u8n-"
let payload = {
data: {
body: 'Message body',
title: 'Message title',
color: "#00ACD4",
priority: "high",
icon: "ic_notif",
show_in_foreground: 'true',
channelId:'sqtrivia-channel'
},
notification: {
title: "Alarm",
subtitle: "First Alarm",
body: "First Alarm",
click_action: "com.myapp.MyCategory" // The id of notification category which you defined with FCM.setNotificationCategories
}
};
let options = { priority: "high", contentAvailable: true };
// Set the message as high priority and have it expire after 24 hours.
console.log('token', token)
if(token){
let d = await admin.messaging().sendToDevice(token, payload, options);
return res.status(200).send({ success: d })
}
return res.status(400).send({ error: 'you should send token' })
} catch (e) {
console.info(e)
return res.status(400).send({ error: 0 })
}
})
AndroidManifest.xml
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="com.moonsite.sqlivetrivia">
<uses-permission Android:name="Android.permission.INTERNET" />
<uses-permission Android:name="Android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission Android:name="Android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission Android:name="Android.permission.VIBRATE" />
<uses-permission Android:name="Android.permission.CAMERA"/>
<uses-permission Android:name="Android.permission.WAKE_LOCK" />
<permission
Android:name="${applicationId}.permission.C2D_MESSAGE"
Android:protectionLevel="signature" />
<uses-permission Android:name="${applicationId}.permission.C2D_MESSAGE" />
<application
Android:name=".MainApplication"
Android:label="@string/app_name"
Android:icon="@mipmap/ic_launcher"
Android:allowBackup="false"
Android:theme="@style/AppTheme">
<receiver
Android:name="com.google.Android.gms.gcm.GcmReceiver"
Android:exported="true"
Android:permission="com.google.Android.c2dm.permission.SEND" >
<intent-filter>
<action Android:name="com.google.Android.c2dm.intent.RECEIVE" />
<category Android:name="${applicationId}" />
</intent-filter>
</receiver>
<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" />
</intent-filter>
</receiver>
<service Android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationRegistrationService"/>
<service
Android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService"
Android:exported="false" >
<intent-filter>
<action Android:name="com.google.Android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<!-- <service Android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService">
<intent-filter>
<action Android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service Android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService">
<intent-filter>
<action Android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service> -->
<service Android:name="io.invertase.firebase.messaging.RNFirebaseBackgroundMessagingService" />
<receiver Android:name="io.invertase.firebase.notifications.RNFirebaseNotificationReceiver"/>
<receiver Android:enabled="true" Android:exported="true" Android:name="io.invertase.firebase.notifications.RNFirebaseNotificationsRebootReceiver">
<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"/>
<category Android:name="Android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<!-- <meta-data
Android:name="com.google.firebase.messaging.default_notification_channel_id"
Android:value="@string/default_notification_channel_id"/> -->
<!-- <meta-data
Android:name="com.google.firebase.messaging.default_notification_icon"
Android:resource="@drawable/ic_stat_ic_notification" />
<meta-data
Android:name="com.google.firebase.messaging.default_notification_color"
Android:resource="@color/colorAccent" /> -->
<activity
Android:name=".MainActivity"
Android:label="@string/app_name"
Android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
Android:windowSoftInputMode="adjustResize"
Android:launchMode="singleTop" >
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity Android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>
</manifest>
前にも言ったように、firebase http関数で送信したときにアプリが実行されている場合にのみ通知を受け取ることに成功しました。今のところAndroidでのみテストしました。
バックグラウンドで送信すると、郵便配達員でテストすると成功の応答が返されます
{
"success": {
"results": [
{
"messageId": "0:1526575831372268%a0cec506f9fd7ecd"
}
],
"canonicalRegistrationTokenCount": 0,
"failureCount": 0,
"successCount": 1,
"multicastId": 8639210245128054000
}
}
しかし、私はデバイスでそれを取得しません(バックグラウンドで)
notification
とdata
の両方のペイロードを持つクラウドメッセージを送信しているように見えます。 Androidアプリがバックグラウンドにある間にメッセージを受信するとウェイクアップするアプリの場合、メッセージはdata
ペイロードでのみ送信できます。
これらのドキュメント、特に「サイレントリモートプッシュ通知」に関する部分をご覧ください: https://github.com/ zo0r/react-native-Push-notification/blob/master/trouble-shooting.md
詳細については、FCMドキュメント: https://firebase.google.com/docs/cloud-messaging/Android/receive
FCMドキュメントから https://firebase.google.com/docs/cloud-messaging/Android/receive
バックグラウンドで制限されたアプリ(Android P以降)
2019年1月以降、FCMはユーザーがバックグラウンド制限に設定したアプリにメッセージを配信しません(設定->アプリと通知-> [アプリ名]->バッテリーなど)。アプリがバックグラウンド制限から削除されると、アプリへの新しいメッセージは以前と同様に配信されます。