React native with Firebase FCM

2019-06-17 10:31发布

I'm trying to implement push notification with React Native and Firebase through this documentation.

I set up the settings I need by the tutorial.

   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>
    )
  }

When I try to use it in postman I get success:

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

But in my debugger (by console.log) I don't see any new incoming message or something else. I sent a message to my device with the token I added to this post but nothing happened.

it works only when app is in foreground, But I want to make it work also when app in background/closed the app

3条回答
相关推荐>>
2楼-- · 2019-06-17 10:57

As mentioned in the docs you need onNotificationOpened listener for android, when the app is in background

Android Background: onNotificationOpened triggered if the notification is tapped.

onNotificationDisplayed is for IOS app in background and triggered if content_available set to true

notificationBackgroundListener = firebase
    .notifications()
    .onNotificationOpened(notification => {
      // Process your notification as required
      console.log(`Recieved notification 2`);
    });
查看更多
何必那么认真
3楼-- · 2019-06-17 11:03

you can use Headless JS to run task in background and you should write some native code to handle task , unfortunately is only available in android
https://facebook.github.io/react-native/docs/headless-js-android.html
second way(i don't test it) is to use this library
https://github.com/jamesisaac/react-native-background-task#installation



ps:firebase and other push notification service like onesignal handle push notification easily and you should not be concerned unless you want unique notification for each user

查看更多
Viruses.
4楼-- · 2019-06-17 11:14

If your notification is working fine when your app is in foreground then the problem is with your service. There are two possible reasons it's not working.

  1. Either you are sending the payload as

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

    instead of

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

which is because the key in notification is recieved only when app is in foreground.

  1. Another possible reason could be the service worker is getting killed for some reason. ex: I was using a one plus which auto kills the service when I force close the app. So you can try debugging your service in native code by adding log or attaching a debugger

also make sure to add google-service.json file in your android/app folder

Edit:

{
 "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"
  }
}

Here is my headers

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

Request:

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

which is of post and params are of raw type

查看更多
登录 后发表回答