当 android 应用程序被杀死时,react-native-push-notification 自定义声音不起作用
react-native-push-notification custom sound not working when android app is killed
我一直在为使用 firebase-admin
版本 ^9.2.0
和 react-native-push-notification
版本 ^5.1.0
.[=26 的 react-native 应用程序添加自定义声音以推送通知=]
我还没有升级到最新版本 react-native-push-notification
的原因是,即使使用正确的频道配置,自定义声音似乎也无法正常工作。我们也在使用 expo,它似乎在使用版本 7+ 时导致启动错误。
我有两个 mp3 文件,名为 regular.mp3
和 mass.mp3
。发送推送通知的 firebase 函数使用公共数据对象发送消息,但也发送推送通知声音的特定于平台的字段:
admin.messaging().send({
data: {
title,
body,
lat: data.Latitude.toString(),
lng: data.Longitude.toString(),
notificationType: data.NotificationType.toString(),
},
notification:{title,body},
apns:{
payload:{
aps:{
alert:{
title,
body,
},
sound: data.NotificationType === 1 ? "mass.mp3" : "regular.mp3",
},
},
},
android: {
priority: "high",
data: {
sound: data.NotificationType === 1 ? "mass" : "regular",
},
notification: {
sound: data.NotificationType === 1 ? "mass" : "regular",
},
},
topic: topic,
})
据我了解,android
下的 data
字段确实包含当应用程序被终止并收到通知时将添加到根级 data
对象的负载.该插件的来源似乎也在使用那个确切的 data
字段来设置通知声音(在 RNReceivedMessageHandler.java 中):
JSONObject data = getPushData(notificationData.get("data"));
if (data != null) {
if (!bundle.containsKey("message")) {
bundle.putString("message", data.optString("alert", null));
}
if (!bundle.containsKey("title")) {
bundle.putString("title", data.optString("title", null));
}
if (!bundle.containsKey("sound")) {
bundle.putString("soundName", data.optString("sound", null));
}
if (!bundle.containsKey("color")) {
bundle.putString("color", data.optString("color", null));
}
这是我目前得到的:
- 当应用程序处于前台时,自定义声音效果很好
- 自定义声音在应用程序处于后台时效果很好
- 当应用程序被杀死时播放默认声音
这是当前用于管理通知的代码:
在index.ts中:
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,
},
popInitialNotification: true,
requestPermissions: true,
});
在App.js
CreateIncidentPushNotification=(remoteMessage)=>{
const {data} = remoteMessage;
PushNotification.localNotification({
title: data.title,
message: data.body,
playSound: true,
soundName: data.notificationType === "1" ? "mass" : "regular",
});
}
我想知道是否还有其他人知道会发生什么。即使应用程序被终止,通知仍然设法到达我的设备,这很棒。唯一缺少的部分是声音。
好的,我终于让它工作了。我必须将以下内容添加到我的清单文件中并评论接收者:
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_name"
android:value="my-channel"/>
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_description"
android:value="my channel"/>
<!-- Change the value to true to enable pop-up for in foreground (remote-only, for local use ignoreInForeground) -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground"
android:value="false"/>
<!-- Change the value to false if you don't want the creation of the default channel -->
<meta-data android:name="com.dieam.reactnativepushnotification.channel_create_default"
android:value="true "/>
<!-- 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" />
</intent-filter>
</receiver> -->
然后,我不得不使用通道来使声音在前台、后台以及应用程序被终止时正常工作。如您所见,我在我的清单文件中创建了一个自定义通道并激活了默认通道。我不得不激活默认频道,因为我有两种需要不同声音的通知类型。使用单个频道是行不通的。
更新清单文件后,我修改了 firebase 函数(使用 firebase-admin
执行以下操作:
admin.messaging().send({
data: {
title,
body,
lat: data.Latitude.toString(),
lng: data.Longitude.toString(),
notificationType: data.NotificationType.toString(),
},
notification:{title,body},
apns:{
payload:{
aps:{
alert:{
title,
body,
},
sound: data.NotificationType === 1 ? "mass.mp3" : "regular.mp3",
},
},
},
android: {
priority: "high",
data: {
sound: data.NotificationType === 1 ? "mass" : "regular",
channelId: data.NotificationType === 1 ? "my-channel" : "fcm_fallback_notification_channel",
},
notification: {
sound: data.NotificationType === 1 ? "mass" : "regular",
channelId: data.NotificationType === 1 ? "my-channel" : "fcm_fallback_notification_channel",
},
},
topic: topic,
})
.then((response) => {
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
Firebase 现在知道我正在使用的两个渠道。然后我转到应用程序代码并像这样处理本地通知:
PushNotification.localNotification({
title: data.title,
message: data.body,
playSound: true,
soundName: data.notificationType === "1" ? "mass" : "regular",
channelId: data.notificationType === "1" ? "my-channel" : "fcm_fallback_notification_channel"
});
我还激活了 react-native-push-notification
包的 onMessage
和 setBackgroundMessageHandler
处理程序:
messaging().onMessage(this.sendMessage);
messaging().setBackgroundMessageHandler(this.sendMessage);
其中this.sendMessage
负责调用上面提到的localNotification
调用。
顺便说一下,当应用程序处于后台时,我仍然收到重复的通知,所以这纯粹是对声音的修复。
更新:
删除 setBackgroundMessageHandler
删除了重复项!!!! :)
和平!
我一直在为使用 firebase-admin
版本 ^9.2.0
和 react-native-push-notification
版本 ^5.1.0
.[=26 的 react-native 应用程序添加自定义声音以推送通知=]
我还没有升级到最新版本 react-native-push-notification
的原因是,即使使用正确的频道配置,自定义声音似乎也无法正常工作。我们也在使用 expo,它似乎在使用版本 7+ 时导致启动错误。
我有两个 mp3 文件,名为 regular.mp3
和 mass.mp3
。发送推送通知的 firebase 函数使用公共数据对象发送消息,但也发送推送通知声音的特定于平台的字段:
admin.messaging().send({
data: {
title,
body,
lat: data.Latitude.toString(),
lng: data.Longitude.toString(),
notificationType: data.NotificationType.toString(),
},
notification:{title,body},
apns:{
payload:{
aps:{
alert:{
title,
body,
},
sound: data.NotificationType === 1 ? "mass.mp3" : "regular.mp3",
},
},
},
android: {
priority: "high",
data: {
sound: data.NotificationType === 1 ? "mass" : "regular",
},
notification: {
sound: data.NotificationType === 1 ? "mass" : "regular",
},
},
topic: topic,
})
据我了解,android
下的 data
字段确实包含当应用程序被终止并收到通知时将添加到根级 data
对象的负载.该插件的来源似乎也在使用那个确切的 data
字段来设置通知声音(在 RNReceivedMessageHandler.java 中):
JSONObject data = getPushData(notificationData.get("data"));
if (data != null) {
if (!bundle.containsKey("message")) {
bundle.putString("message", data.optString("alert", null));
}
if (!bundle.containsKey("title")) {
bundle.putString("title", data.optString("title", null));
}
if (!bundle.containsKey("sound")) {
bundle.putString("soundName", data.optString("sound", null));
}
if (!bundle.containsKey("color")) {
bundle.putString("color", data.optString("color", null));
}
这是我目前得到的:
- 当应用程序处于前台时,自定义声音效果很好
- 自定义声音在应用程序处于后台时效果很好
- 当应用程序被杀死时播放默认声音
这是当前用于管理通知的代码:
在index.ts中:
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,
},
popInitialNotification: true,
requestPermissions: true,
});
在App.js
CreateIncidentPushNotification=(remoteMessage)=>{
const {data} = remoteMessage;
PushNotification.localNotification({
title: data.title,
message: data.body,
playSound: true,
soundName: data.notificationType === "1" ? "mass" : "regular",
});
}
我想知道是否还有其他人知道会发生什么。即使应用程序被终止,通知仍然设法到达我的设备,这很棒。唯一缺少的部分是声音。
好的,我终于让它工作了。我必须将以下内容添加到我的清单文件中并评论接收者:
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_name"
android:value="my-channel"/>
<meta-data android:name="com.dieam.reactnativepushnotification.notification_channel_description"
android:value="my channel"/>
<!-- Change the value to true to enable pop-up for in foreground (remote-only, for local use ignoreInForeground) -->
<meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground"
android:value="false"/>
<!-- Change the value to false if you don't want the creation of the default channel -->
<meta-data android:name="com.dieam.reactnativepushnotification.channel_create_default"
android:value="true "/>
<!-- 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" />
</intent-filter>
</receiver> -->
然后,我不得不使用通道来使声音在前台、后台以及应用程序被终止时正常工作。如您所见,我在我的清单文件中创建了一个自定义通道并激活了默认通道。我不得不激活默认频道,因为我有两种需要不同声音的通知类型。使用单个频道是行不通的。
更新清单文件后,我修改了 firebase 函数(使用 firebase-admin
执行以下操作:
admin.messaging().send({
data: {
title,
body,
lat: data.Latitude.toString(),
lng: data.Longitude.toString(),
notificationType: data.NotificationType.toString(),
},
notification:{title,body},
apns:{
payload:{
aps:{
alert:{
title,
body,
},
sound: data.NotificationType === 1 ? "mass.mp3" : "regular.mp3",
},
},
},
android: {
priority: "high",
data: {
sound: data.NotificationType === 1 ? "mass" : "regular",
channelId: data.NotificationType === 1 ? "my-channel" : "fcm_fallback_notification_channel",
},
notification: {
sound: data.NotificationType === 1 ? "mass" : "regular",
channelId: data.NotificationType === 1 ? "my-channel" : "fcm_fallback_notification_channel",
},
},
topic: topic,
})
.then((response) => {
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
Firebase 现在知道我正在使用的两个渠道。然后我转到应用程序代码并像这样处理本地通知:
PushNotification.localNotification({
title: data.title,
message: data.body,
playSound: true,
soundName: data.notificationType === "1" ? "mass" : "regular",
channelId: data.notificationType === "1" ? "my-channel" : "fcm_fallback_notification_channel"
});
我还激活了 react-native-push-notification
包的 onMessage
和 setBackgroundMessageHandler
处理程序:
messaging().onMessage(this.sendMessage);
messaging().setBackgroundMessageHandler(this.sendMessage);
其中this.sendMessage
负责调用上面提到的localNotification
调用。
顺便说一下,当应用程序处于后台时,我仍然收到重复的通知,所以这纯粹是对声音的修复。
更新:
删除 setBackgroundMessageHandler
删除了重复项!!!! :)
和平!