【问题标题】:React native with Firebase FCM使用 Firebase FCM 反应原生
【发布时间】:2018-04-29 14:54:05
【问题描述】:

我正在尝试通过this documentation 使用 React Native 和 Firebase 实现推送通知。

我按照教程设置了我需要的设置。

   import React, { Component } from 'react'
import { View } from 'react-native'
import { Input, Text, Button } from '../Components'
import type { RemoteMessage } from 'react-native-firebase'
import firebase from 'react-native-firebase'
import type { Notification, NotificationOpen } from 'react-native-firebase';

export default class TestComponent extends Component {

  async componentDidMount() {
    await this.SetUpAuth();
    await this.SetUpMessaging();
    this.notificationOpenedListener = firebase.notifications().onNotificationOpened((notificationOpen: NotificationOpen) => {
      // Get the action triggered by the notification being opened
      const action = notificationOpen.action;
      // Get information about the notification that was opened
      const notification: Notification = notificationOpen.notification;
    });
    const notificationOpen: NotificationOpen = await firebase.notifications().getInitialNotification();
    if (notificationOpen) {
      console.log(notificationOpen)
      // App was opened by a notification
      // Get the action triggered by the notification being opened
      const action = notificationOpen.action;
      // Get information about the notification that was opened
      const notification: Notification = notificationOpen.notification;
    }


  }
  componentWillUnmount() {

  }


  async SetUpAuth() {
    const credential = await firebase.auth().signInAnonymouslyAndRetrieveData();
    if (credential) {
      console.log('default app user ->', credential.user.toJSON());
    } else {
      console.error('no credential');
    }
  }
  async SetUpMessaging() {
    this.notification2 = new firebase.notifications.Notification()
      .setNotificationId('notificationId')
      .setTitle('My notification title')
      .setBody('My notification body')
      .android.setChannelId('test')
      .android.setClickAction('action')
      .setData({
        key1: 'value1',
        key2: 'value2',
      });

    this.notification2
      .android.setChannelId('channelId')
      .android.setSmallIcon('ic_launcher');
    console.log('assa')

    onTokenRefreshListener = firebase.messaging().onTokenRefresh(fcmToken => {
      console.log('token generated ->', fcmToken);
      //   store.dispatch(DeviceActions.SetFCMToken(fcmToken));
    });

    const fcmToken = await firebase.messaging().getToken();
    if (fcmToken) {
      // user has a device token
      console.log('has token ->', fcmToken);
      console.log(firebase.auth().currentUser._user)
      firebase.database().ref(`/users/${firebase.auth().currentUser._user.uid}`).set({ pushToken: fcmToken })
      //   store.dispatch(DeviceActions.SetFCMToken(fcmToken));
    } else {
      // user doesn't have a device token yet
      console.error('no messaging token');
    }

    const messagingEnabled = await firebase.messaging().hasPermission();
    if (messagingEnabled) {
      // user has permissions
      console.log('User has FCM permissions');
    } else {
      // user doesn't have permission
      console.log('User does not have FCM permissions');
      await this.RequestMessagePermissions();
    }

    messageListener = firebase.messaging().onMessage((message: RemoteMessage) => {
      console.log(`Recieved message - ${JSON.stringify(message)}`);
    });

    notificationDisplayedListener = firebase
      .notifications()
      .onNotificationDisplayed(notification => {
        // Process your notification as required
        // ANDROID: Remote notifications do not contain the channel ID. You will have to specify this manually if you'd like to re-display the notification.
        console.log(`Recieved notification 1`);
      });
    notificationListener = firebase
      .notifications()
      .onNotification(notification => {
        console.log(notification)
        firebase.notifications().displayNotification(this.notification2)
        // Process your notification as required
        console.log(`Recieved notification 2`);
      });
  }


  async RequestMessagePermissions() {
    console.log('request')
    console.log('Requesting FCM permission');
    await firebase
      .messaging()
      .requestPermission()
      .catch(err => console.err(err));
  }


  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>

      </View>
    )
  }

当我尝试在邮递员中使用它时,我得到了成功:

{
  "success": {
    "results": [
        {
            "messageId": "0:1525013439417985%a0cec506a0cec506"
        }
    ],
    "canonicalRegistrationTokenCount": 0,
    "failureCount": 0,
    "successCount": 1,
    "multicastId": 6840884736220792000
  }
}

但在我的调试器中(通过 console.log),我没有看到任何新的传入消息或其他内容。我使用添加到此帖子中的令牌向我的设备发送了一条消息,但没有任何反应。

它仅在应用程序处于前台时有效,但我想让它在应用程序在后台/关闭应用程序时也能工作

【问题讨论】:

  • 你是在安卓还是ios上测试?
  • 我在安卓中测试过。在android中运行后,我将在ios中进行测试

标签: javascript firebase react-native firebase-cloud-messaging


【解决方案1】:

正如docs 中提到的,当应用程序处于后台时,您需要onNotificationOpened 监听器来监听android

Android 背景onNotificationOpened 在通知被点击时触发。

onNotificationDisplayed 用于 IOS 后台应用triggered if content_available set to true

notificationBackgroundListener = firebase
    .notifications()
    .onNotificationOpened(notification => {
      // Process your notification as required
      console.log(`Recieved notification 2`);
    });

【讨论】:

  • 我添加了我的帖子并添加了监听器,但仍然是同样的问题。你可以看到我在 componentDidMount 上调用它
  • 只有当notification被点击时它才会起作用,也可以尝试定义和记录你的监听器,就像在SetUpMessaging模块和getInitialNotification只在点击通知打开时被调用应用程序。
  • 我正在尝试了解如何发出通知,因为本地通知会向我显示图标并且效果很好,而且当我在前台时也是如此。但在背景中我什么也没看到
  • 所以在前台看到通知但在后台没有通知?
  • 正确。在前台我看到是因为我声明它 firebase.notifications().displayNotification(this.notification2)
【解决方案2】:

如果您的应用在前台运行时通知工作正常,那么问题出在您的服务上。它不起作用有两个可能的原因。

  1. 要么您将有效负载发送为

    {   
         time_to_live: 86400,
         collapse_key: "xxxxxx",
         delay_while_idle: false,
         registration_ids: registration_ids,
         notification: payload
     }
    

    而不是

      {
           time_to_live: 86400,
            collapse_key: "xxxxxx",
            delay_while_idle: false,
            registration_ids: registration_ids,
            data: payload
      }
    

这是因为只有在应用程序处于前台时才会收到通知中的键。

  1. 另一个可能的原因可能是服务人员因某种原因被杀死。例如:我使用了一加,当我强制关闭应用程序时会自动终止服务。因此,您可以尝试通过添加日志或附加调试器来使用本机代码调试您的服务

还要确保在您的 android/app 文件夹中添加 google-service.json 文件

编辑

{
 "registration_ids" : ["reg_id"],
 "time_to_live": 86400,
  "collapse_key": "test_type_b",
  "delay_while_idle": false,

  "notification": {},   
  "data": {
    "subText":"sub title R",
    "title":"Notification Heading R",
    "message":"Short big text that will be shown when notification is expanded R",
    "color":"red",
    "actions": ["hello", "welcome"],
    "vibrate": true,
    "vibration": 1000,
    "ticker": "My Notification Ticker",
    "imageUrl": "https://cdn-images-1.medium.com/max/712/1*c3cQvYJrVezv_Az0CoDcbA.jpeg" ,
    "bigText": "blalMy big text that will be shown when notification is expanded"
  }
}

这是我的标题

Authorization: key=mykey:myKey
Content-Type: application/json

请求:

 https://fcm.googleapis.com/fcm/send 

post 和 params 是 raw 类型

【讨论】:

  • 什么是折叠键?我将谷歌服务添加到我的项目中。我怎么知道是否有服务人员被杀?在 react-native-firebase 文档中,我只需要添加运行 service-worker 的配置,而无需我自己的代码
  • github.com/invertase/react-native-firebase/blob/master/android/… 这是将根据您共享的文档接收的服务,在某处添加日志并在 android studio 日志中监控它们(我遵循的方法应该还有其他更好的解决方案)
  • 让我尝试更新答案
  • bitbucket.org/ideaboard_tech/push-notifications/src/ib-master/… 这是我的带有 fcm 支持的 react-native-push-notifications 的分叉版本
  • 谢谢。你还有这个包与firebase-function一起工作的例子吗?我的意思是使用这个库和 firebase 函数发送推送通知
【解决方案3】:

你可以使用 Headless JS 在后台运行任务,你应该编写一些本地代码来处理任务,不幸的是只在 android 中可用
https://facebook.github.io/react-native/docs/headless-js-android.html
第二种方法(我不测试)是使用这个库
https://github.com/jamesisaac/react-native-background-task#installation



ps:firebase 和其他推送通知服务(如 onesignal)很容易处理推送通知,除非您希望为每个用户提供唯一通知,否则您不应该担心

【讨论】:

  • 嘿,我不确定我需要在更多包中使用。我已经使用 react-native-firebase 并且它应该可以工作,但我不知道为什么..另外我尝试了 react-native-fcm 但它同样的问题。仅在前台工作。我很高兴在 Firebase 中轻松听到推送通知,但我几乎一整天都坚持使用它。
  • 你有什么要为每个用户自定义通知
  • 没有。我想用 react-native-firebase 定期通知。
  • 如果你可以在后台收到通知但不解析他们的数据,你可以在firebase中启用深度链接,它会自动启动你的应用程序,在js端你可以解析数据
  • 看这个例子你应该在原生端实现并在js端与数据交互tatvic.com/blog/…
猜你喜欢
  • 1970-01-01
  • 2021-05-28
  • 2019-04-23
  • 1970-01-01
  • 2020-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-13
相关资源
最近更新 更多