当应用程序在后台使用 firebase 时,使推送通知显示为弹出窗口
Make push notifications appear as pop up when app is on background with firebase
我正在使用我的 React 本机应用程序向使用 Firebase 云消息传递的 android 用户设置推送通知。到目前为止,我主要关注 这个tutorial。我设法使推送通知显示在锁定屏幕上,并在应用程序处于前台时处理它们。但是,当应用程序在后台运行时,我无法将通知显示为弹出窗口。它出现在通知托盘上,但不会像 gmail 或 whatsapp 的通知那样显示弹出窗口。
我认为我的问题是我没有在消息中发送正确的参数。我正在使用 firebase 控制台,所以它不是很灵活。我如何配置(以编程方式)通知在收到时显示为弹出窗口?
编辑:
设置通知通道适用于较新的 android 设备 - 在 Android 8.1(API 级别 27)上测试。
在较旧的设备上 - 在 Android 6.0(API 级别 23)上进行测试 - 提示通知仍然不会出现。我正在使用 aws sns 控制台发送以下消息:
{
priority: 'high',
content_available: true,
notification: {
title: 'hello',
body: 'Just test',
android_channel_id: 'test-channel',
sound: 'default'
},
data: { title: 'title', body: 'body', sound: 'default' }
}
我还使用 Firebase 控制台设置“高优先级”和“启用声音”发送消息,有和没有 Android 频道 ID。 None 其中有效。通知静静地到达托盘栏。这个 discussion shows the same problems, but the solution 一个人指出的对我不起作用。我没有经常编辑 react-native 库代码。我尝试了 旧 Android 版本的问题(前景),它使抬头出现在前景上,但不出现在背景上,这是这里的预期行为。
此外,对于使用这个 React Native 包的很多人来说,这似乎是一个未解决的问题 (github issue, github issue)。
所以,我想我应该重新表述我的问题。对于 Android 7.1 或更低版本(在 6.0 上测试):
设置 priority='high' 和 notification.sound='default' 是否足以显示提醒通知? (根据我的研究应该是)
我是否需要对我的应用程序代码进行任何进一步的配置,以从通知静默到达托盘栏到它作为提示出现?
要像 whatsApp 一样在弹出窗口中显示通知,您应该使用 IMPORTANCE_HIGH
设置您的通知渠道重要性
来自官方文档here
Makes a sound and appears as a heads-up notification
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance)
编辑:
对于设备 运行 lollipop --> Nougat ,您需要设置振动或铃声才能制作 Heads-up工作。但是,这里有一个不需要 VIBRATE 权限即可生成 head-up 通知的快速技巧。 link
notificationBuilder.setPriority(Notification.PRIORITY_HIGH);
if (Build.VERSION.SDK_INT >= 21) notificationBuilder.setVibrate(new long[0]);
感谢@ismailalaoui 对这个问题的贡献。当系统托盘收到通知时,我无法将通知显示为抬头,因此我不得不进行变通。我将用 react-native-firebase.
展示我是如何做到的
对于新 android 设备,you should create a notification channel。在您的 App.js
中添加以下内容
componentDidMount(){
...
const channel = new firebase.notifications.Android.Channel('test-channel', 'Test Channel', firebase.notifications.Android.Importance.Max).setDescription('My apps test channel'); //add this line
firebase.notifications().android.createChannel(channel); //add this line
}
对于旧设备,我不得不进行变通。我没有使用通知消息,而是使用了数据消息,因此您可以在后台收听。 See item 4。
先新建一个文件bgMessaging.js:
import firebase from 'react-native-firebase';
export default async (message) => {
// handle your message
const notification = new firebase.notifications.Notification()
.setNotificationId(message.messageId)
.setTitle(message.data.title)
.setBody(message.data.body)
.android.setChannelId('test-channel')
.android.setSmallIcon('ic_launcher')
.android.setPriority(firebase.notifications.Android.Priority.Max)
.setSound('default');
await firebase.notifications().displayNotification(notification);
console.log({message})
return Promise.resolve();
}
在您的 index.js 文件中,添加:
import bgMessaging from './src/bgMessaging'; // <-- Import the file you just created
...
AppRegistry.registerHeadlessTask('RNFirebaseBackgroundMessage', () => bgMessaging);
react-native-firebase 使用 Headless JS 来 运行 您在 bgMessaging
中定义的 javascript 代码。根据 docs,您需要将服务添加到 AndroidManifest.xml。
在 android/app/src/main/AndroidManifest.xml 添加:
<application>
...
<service android:name="io.invertase.firebase.messaging.RNFirebaseBackgroundMessagingService" /> <!--Add this-->
...
</application>
对于 react-native-firebase v6:
要创建频道,请将以下行添加到 MainActivity.java
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;
protected void onCreate(Bundle savedInstanceState) {
// any other code goes here
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel("500", "MainChannel", NotificationManager.IMPORTANCE_HIGH);
notificationChannel.setShowBadge(true);
notificationChannel.setDescription("Test Notifications");
notificationChannel.enableVibration(true);
notificationChannel.enableLights(true);
notificationChannel.setVibrationPattern(new long[]{400, 200, 400});
//notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(notificationChannel);
}
}
这是服务器发送的消息
const message = {
notification: {
title: data.subject,
body: data.message,
},
data: {
id: data.id,
title: data.subject,
body: data.message,
origin: 'chat',
request: 'test'
},
android: {
priority: 'high',
notification: {
title: data.subject,
body: data.message,
sound: 'default',
priority: 'high',
channelId: '500'
}
},
token: "TOKEN"
};
//firebase admin
admin.messaging().send(message)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
在 GitHub 问题线程上找到了这个答案。所有功劳归功于他们。
在 android Nougat(v7) 和 Pie(v9)
上测试
我正在使用我的 React 本机应用程序向使用 Firebase 云消息传递的 android 用户设置推送通知。到目前为止,我主要关注 这个tutorial。我设法使推送通知显示在锁定屏幕上,并在应用程序处于前台时处理它们。但是,当应用程序在后台运行时,我无法将通知显示为弹出窗口。它出现在通知托盘上,但不会像 gmail 或 whatsapp 的通知那样显示弹出窗口。
我认为我的问题是我没有在消息中发送正确的参数。我正在使用 firebase 控制台,所以它不是很灵活。我如何配置(以编程方式)通知在收到时显示为弹出窗口?
编辑:
设置通知通道适用于较新的 android 设备 - 在 Android 8.1(API 级别 27)上测试。
在较旧的设备上 - 在 Android 6.0(API 级别 23)上进行测试 - 提示通知仍然不会出现。我正在使用 aws sns 控制台发送以下消息:
{
priority: 'high',
content_available: true,
notification: {
title: 'hello',
body: 'Just test',
android_channel_id: 'test-channel',
sound: 'default'
},
data: { title: 'title', body: 'body', sound: 'default' }
}
我还使用 Firebase 控制台设置“高优先级”和“启用声音”发送消息,有和没有 Android 频道 ID。 None 其中有效。通知静静地到达托盘栏。这个 discussion shows the same problems, but the solution 一个人指出的对我不起作用。我没有经常编辑 react-native 库代码。我尝试了 旧 Android 版本的问题(前景),它使抬头出现在前景上,但不出现在背景上,这是这里的预期行为。
此外,对于使用这个 React Native 包的很多人来说,这似乎是一个未解决的问题 (github issue, github issue)。
所以,我想我应该重新表述我的问题。对于 Android 7.1 或更低版本(在 6.0 上测试):
设置 priority='high' 和 notification.sound='default' 是否足以显示提醒通知? (根据我的研究应该是)
我是否需要对我的应用程序代码进行任何进一步的配置,以从通知静默到达托盘栏到它作为提示出现?
要像 whatsApp 一样在弹出窗口中显示通知,您应该使用 IMPORTANCE_HIGH
来自官方文档here
Makes a sound and appears as a heads-up notification
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance)
编辑:
对于设备 运行 lollipop --> Nougat ,您需要设置振动或铃声才能制作 Heads-up工作。但是,这里有一个不需要 VIBRATE 权限即可生成 head-up 通知的快速技巧。 link
notificationBuilder.setPriority(Notification.PRIORITY_HIGH);
if (Build.VERSION.SDK_INT >= 21) notificationBuilder.setVibrate(new long[0]);
感谢@ismailalaoui 对这个问题的贡献。当系统托盘收到通知时,我无法将通知显示为抬头,因此我不得不进行变通。我将用 react-native-firebase.
展示我是如何做到的对于新 android 设备,you should create a notification channel。在您的 App.js
中添加以下内容componentDidMount(){
...
const channel = new firebase.notifications.Android.Channel('test-channel', 'Test Channel', firebase.notifications.Android.Importance.Max).setDescription('My apps test channel'); //add this line
firebase.notifications().android.createChannel(channel); //add this line
}
对于旧设备,我不得不进行变通。我没有使用通知消息,而是使用了数据消息,因此您可以在后台收听。 See item 4。
先新建一个文件bgMessaging.js:
import firebase from 'react-native-firebase';
export default async (message) => {
// handle your message
const notification = new firebase.notifications.Notification()
.setNotificationId(message.messageId)
.setTitle(message.data.title)
.setBody(message.data.body)
.android.setChannelId('test-channel')
.android.setSmallIcon('ic_launcher')
.android.setPriority(firebase.notifications.Android.Priority.Max)
.setSound('default');
await firebase.notifications().displayNotification(notification);
console.log({message})
return Promise.resolve();
}
在您的 index.js 文件中,添加:
import bgMessaging from './src/bgMessaging'; // <-- Import the file you just created
...
AppRegistry.registerHeadlessTask('RNFirebaseBackgroundMessage', () => bgMessaging);
react-native-firebase 使用 Headless JS 来 运行 您在 bgMessaging
中定义的 javascript 代码。根据 docs,您需要将服务添加到 AndroidManifest.xml。
在 android/app/src/main/AndroidManifest.xml 添加:
<application>
...
<service android:name="io.invertase.firebase.messaging.RNFirebaseBackgroundMessagingService" /> <!--Add this-->
...
</application>
对于 react-native-firebase v6:
要创建频道,请将以下行添加到 MainActivity.java
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;
protected void onCreate(Bundle savedInstanceState) {
// any other code goes here
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel("500", "MainChannel", NotificationManager.IMPORTANCE_HIGH);
notificationChannel.setShowBadge(true);
notificationChannel.setDescription("Test Notifications");
notificationChannel.enableVibration(true);
notificationChannel.enableLights(true);
notificationChannel.setVibrationPattern(new long[]{400, 200, 400});
//notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(notificationChannel);
}
}
这是服务器发送的消息
const message = {
notification: {
title: data.subject,
body: data.message,
},
data: {
id: data.id,
title: data.subject,
body: data.message,
origin: 'chat',
request: 'test'
},
android: {
priority: 'high',
notification: {
title: data.subject,
body: data.message,
sound: 'default',
priority: 'high',
channelId: '500'
}
},
token: "TOKEN"
};
//firebase admin
admin.messaging().send(message)
.then((response) => {
// Response is a message ID string.
console.log('Successfully sent message:', response);
})
.catch((error) => {
console.log('Error sending message:', error);
});
在 GitHub 问题线程上找到了这个答案。所有功劳归功于他们。 在 android Nougat(v7) 和 Pie(v9)
上测试