web-dev-qa-db-fra.com

React natif avec Firebase FCM

J'essaie d'implémenter les notifications Push avec React Native et Firebase via cette documentation .

J'ai configuré les paramètres dont j'ai besoin dans le tutoriel.

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

Quand j'essaye de l'utiliser dans postman, j'ai du succès:

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

Mais dans mon débogueur (par console.log), je ne vois aucun nouveau message entrant ni autre chose. J'ai envoyé un message à mon appareil avec le jeton que j'ai ajouté à ce message, mais rien ne s'est passé.

cela ne fonctionne que lorsque l'application est au premier plan, mais je veux que cela fonctionne également lorsque l'application est en arrière-plan/fermée de l'application 

7
Adir Zoari

Comme indiqué dans le docs _ vous avez besoin du programme d'écoute onNotificationOpened pour Android, lorsque l'application est en arrière-plan.

Android Background: onNotificationOpened déclenché si la notification est exploitée.

onNotificationDisplayed est pour IOS application en arrière-plan et triggered if content_available set to true 

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

Si votre notification fonctionne correctement lorsque votre application est au premier plan, le problème provient de votre service. Cela ne fonctionne pas pour deux raisons. 

  1. Soit vous envoyez la charge en tant que 

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

    au lieu de 

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

c'est parce que la clé dans la notification n'est reçue que lorsque l'application est au premier plan.

  1. Une autre raison possible pourrait être le travailleur de service est tué pour une raison quelconque. ex: J'utilisais un one plus qui tue automatiquement le service quand je force la fermeture de l'application. Vous pouvez donc essayer de déboguer votre service en code natif en ajoutant un journal ou en joignant un débogueur

veillez également à ajouter le fichier google-service.json dans votre dossier Android/app

Modifier :

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

Voici mes en-têtes 

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

Demande:

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

qui est de post et params sont de type brut

1

vous pouvez utiliser Headless JS pour exécuter une tâche en arrière-plan et vous devez écrire du code natif pour gérer cette tâche. Malheureusement, cette option est uniquement disponible dans Android
https://facebook.github.io/react-native/docs/headless-js-Android.html
La deuxième façon (je ne teste pas) est d'utiliser cette bibliothèque 
https://github.com/jamesisaac/react-native-background-task#installation



ps: firebase et autres services de notification Push tels que onesignal gèrent facilement les notifications Push. Ne vous inquiétez pas, sauf si vous souhaitez une notification unique pour chaque utilisateur. 

0
nima_moradi