【问题标题】:React Native: Handle silent push notificationReact Native:处理静默推送通知
【发布时间】:2019-06-10 10:36:39
【问题描述】:

我正在使用react-native-firebase 处理我们的 React Native 应用程序(适用于 Android 和 iOS)的推送通知。

我注意到只有 1 个回调用于在应用程序运行(前台或后台)时收到的推送通知,而不是在其关闭或终止时收到。

firebase
.notifications()
.onNotification(notification => {
    console.log('Notification received');
);

但是如果应用被关闭或杀死,它只会将通知放在托盘中,不会执行上面的console.log。

然后输入静默推送通知。所以当我只是在通知的有效负载中发送数据部分时,即使应用程序在前台,也不会触发上面的回调。

我没有看到其他有助于接收静默推送通知的回调。

那么我们如何在 javascript 部分处理推送通知呢?

【问题讨论】:

  • 我也有同样的问题,但我正在使用 OneSignal 进行推送通知服务!我已经达到了学习无头 js 组件的目的
  • 也许我们可以建立一个聊天室一起讨论这个问题
  • 还有一些其他的包,如 react-native-background、react-native-fetch、react-native-qeue,它们对 ios 和 android 的场景都有帮助!我也在调查那些!你能分享你到目前为止搜索的内容吗?请
  • 目前,我还没有查看其他 RN 库的推送通知;只有这一个。我能够在 Android 部分处理静默推送通知。但它有一些复杂性,比如如果我在那里处理它,那么 javascript 回调将停止工作。
  • 你为此做了后台服务!先生,您能分享一下吗?

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


【解决方案1】:

您不需要其他答案中建议的其他软件包。 使用 RNFirebase.io,你可以轻松搞定。

如果您在应用程序处于后台时收到通知,您必须自己处理才能显示此通知。例如,请参阅我的 init-Method for Push-Notifications。

  import firebase from 'react-native-firebase';
  const notifications = firebase.notifications();
  ....
  notifications.onNotification((notif) => {
    notif.android.setChannelId('app-infos');
    notifications.displayNotification(notif);
  });

您可以使用displayNotification 进行操作。但请确保在调用它之前设置通知通道,否则它无法在 >= Android 8.0 上运行

顺便说一句确保您完全设置 Firebase 并授予所有必要的权限,以便在应用关闭或在后台时能够监听通知。 (https://rnfirebase.io/docs/v5.x.x/notifications/android)

附录

我添加这个作为示例来展示我如何将 firebase-notification-stuff 实现为一个小型库(如果您不需要它,请删除 redux-stuff):

import firebase from 'react-native-firebase';
import { saveNotificationToken } from 'app/actions/firebase';
import reduxStore from './reduxStore';
import NavigationService from './NavigationService';

const messaging = firebase.messaging();
const notifications = firebase.notifications();
const crashlytics = firebase.crashlytics();

function registerNotifChannels() {
  try {
    // Notification-Channels is a must-have for Android >= 8
    const channel = new firebase.notifications.Android.Channel(
      'app-infos',
      'App Infos',
      firebase.notifications.Android.Importance.Max,
    ).setDescription('General Information');

    notifications.android.createChannel(channel);
  } catch (error) {
    crashlytics.log(`Error while creating notification-channel \n ${error}`);
  }
}

// This is the Promise object that we use to initialise the push
// notifications. It will resolve when the token was successfully retrieved. The
// token is returned as the value of the Promise.
const initPushNotifs = new Promise(async (resolve, reject) => {
  try {
    const isPermitted = await messaging.hasPermission();

    if (isPermitted) {
      registerNotifChannels();

      try {
        const token = await messaging.getToken();
        if (token) {
          resolve(token);
        }
      } catch (error) {
        crashlytics.log(`Error: failed to get notification-token \n ${error}`);
      }
    }
  } catch (error) {
    crashlytics.log(`Error while checking notification-permission\n ${error}`);
  }

  // If we get this far then there was no token available (or something went
  // wrong trying to get it)
  reject();
});

function init() {
  // Initialise the push notifications, then save the token when/if it's available
  initPushNotifs.then(token => reduxStore.dispatch(saveNotificationToken(token)));

  // Save the (new) token whenever it changes
  messaging.onTokenRefresh(token => reduxStore.dispatch(saveNotificationToken(token)));

  notifications.onNotification((notif) => {
    notif.android.setChannelId('app-infos');
    notifications.displayNotification(notif);
  });

  notifications.onNotificationOpened((notif) => {
    const { notification: { _data: { chatroom: chatRoomId } } = {} } = notif;

    if (chatRoomId) {
      NavigationService.navigate('ChatRoom', { chatRoomId });
    }
  });
}

export default {
  init,
};

有了这个,只需转到您的 index.js 文件(或您的应用程序的根文件,无论它如何命名)并调用 init-Metod:

...
import LPFirebase from 'lib/LPFirebase';

LPFirebase.init();

【讨论】:

  • onNotification 仅在应用启动时触发(前台或后台)。如果应用程序被杀死或关闭,这里的场景。所以你的javascript部分根本不会被调用。
  • 奇怪,因为它对我有用。我创建了一个小型库来连接 firebase 并在我的 index.js 中调用我的 init()-Method。我会加强上面的评论,这样你就可以看到它是如何为我工作的。
  • 您好。你可以分享你的整个代码吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-17
  • 2018-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多