【问题标题】:Make push notifications appear as pop up when app is on background with firebase当应用程序在后台使用 Firebase 时,使推送通知显示为弹出窗口
【发布时间】:2019-10-30 11:02:39
【问题描述】:

我正在使用我的 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 控制台设置 Priority High 和 Sound Enabled 发送消息,有无 Android Channel Id。这些都没有奏效。通知以静默方式到达托盘栏。这个discussion 显示了同样的问题,但是一个人指出的solution 对我不起作用。我没有过多地编辑 react-native 库代码。我尝试了 Problems with old Android version (Foreground) 部分,它使抬头出现在前台,而不是在后台,这是这里的预期行为。

此外,对于很多使用这个 react native 包的人来说,这似乎是一个未解决的问题(github issuegithub issue)。

所以,我想我应该重新提出我的问题。对于 Android 7.1 或更低版本(在 6.0 上测试):

  1. 设置 priority='high' 和 notification.sound='default' 是否足以显示抬头通知? (根据我的研究应该是)

  2. 我是否需要对我的应用程序代码进行任何进一步的配置,以从通知以静默方式到达托盘栏变为提示出现?

【问题讨论】:

  • 您真的在使用 GCM 吗?它已被弃用。您应该改用 FCM。此外,FCM 文档解释了您所描述的内容。你看过那个文档了吗?
  • 我确实在使用 FCM。我已经打乱了这些概念。谢谢你的评论。我会在我的帖子中更正它。
  • 您是否查看了 FCM 文档以确定它是否告诉您需要做什么?
  • 我发现这个page 指定了 FCM 的消息属性。不过,我没有看到任何与显示相关的属性是否在背景上弹出。我还通过 firebase 和 firebase-react-native 文档检查了设置说明是否与教程中的相符。
  • 请检查我的答案

标签: android firebase react-native push-notification react-native-firebase


【解决方案1】:

感谢@ismailalaoui 为这个问题做出贡献。当系统托盘收到通知时,我无法将通知显示为抬头,所以我不得不解决问题。我将展示我是如何使用 react-native-firebase 做到的。

对于新的安卓设备,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>

【讨论】:

    【解决方案2】:

    要像whatsApp一样在弹出窗口中显示通知,您应该使用IMPORTANCE_HIGH设置您的通知渠道重要性

    来自官方文档here

    发出声音并显示为提醒通知

    int importance = NotificationManager.IMPORTANCE_HIGH;
    NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance)
    

    编辑:

    对于运行 lollipop --> Nougat 的设备,您需要设置振动或铃声以使 Heads-up 工作。然而,这里有一个不需要 VIBRATE 权限来产生抬头通知的快速技巧。 link

    notificationBuilder.setPriority(Notification.PRIORITY_HIGH);
    if (Build.VERSION.SDK_INT >= 21) notificationBuilder.setVibrate(new long[0]);
    

    【讨论】:

    • 感谢您的回答。这适用于 android 8.1。对于 android 6.0,通知仍然不会显示为抬头。我已经编辑了我的问题,请看一下。
    • 供将来参考,this 是在 react native 上使用 react-native-firebase 创建通知通道的方式
    • 我应该把这段代码放在哪里?在我的客户端或服务器上?因为当收到通知时,只有后台消息it goes straight to System Tray。代码的任何部分在收到时是否与仅通知消息交互?如果您打算在发送消息时在服务器上包含此代码,那么在 firebase 控制台上启用配置声音的优先级是否足以做到这一点?
    • 你应该把它放在移动端的通知生成器中!
    • 你能说得更具体一点吗?我已将您的代码放在应用程序运行时可以使用的通知生成器上。它对后台通知没有任何作用。我对android代码不是很熟悉。我确实看了一下内部并可以完成修改,但我需要知道我在寻找什么。我正在使用 react-native-firebase,因此丢失了很多库代码。
    【解决方案3】:

    对于 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)

    上测试

    【讨论】:

      猜你喜欢
      • 2018-11-11
      • 1970-01-01
      • 1970-01-01
      • 2018-08-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-08
      • 1970-01-01
      相关资源
      最近更新 更多