реагировать на собственное push-уведомление firebase, когда приложение закрывается / удаляется из списка - PullRequest
0 голосов
/ 30 апреля 2018

Я пытаюсь показать push-уведомление, когда приложение закрыто, поэтому я настраиваю push-уведомление с response-native-firebase с this docs

Я установил AndroidManifest.xml, как описано в документации

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.moonsite.sqlivetrivia"
    android:versionCode="1"
    android:versionName="1.0">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="22" />

    <application
      android:name=".MainApplication"
      android:allowBackup="true"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:theme="@style/AppTheme">
      <receiver android:name="io.invertase.firebase.notifications.RNFirebaseNotificationReceiver"/>
  <receiver android:enabled="true" android:exported="true"  android:name="io.invertase.firebase.notifications.RNFirebaseNotificationsRebootReceiver">
    <intent-filter>
      <action android:name="android.intent.action.BOOT_COMPLETED"/>
      <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
      <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
      <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
  </receiver>
  <meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/ic_stat_ic_notification" />
      <meta-data
    android:name="com.google.firebase.messaging.default_notification_color"
    android:resource="@color/colorAccent" />
       <!-- 

      <meta-data
    android:name="com.google.firebase.messaging.default_notification_channel_id"
    android:value="@string/default_notification_channel_id"/> -->
      <service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService">
        <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    <service android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService">
        <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
        </intent-filter>
    </service>
      <service android:name="io.invertase.firebase.messaging.RNFirebaseBackgroundMessagingService" />

      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="adjustResize"
        android:launchMode="singleTop"

        >
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>
      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    </application>

</manifest>

тогда я написал код в реагировать родной

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

Затем я создал http-функцию firebase только для теста

export const sendNotification = functions.https
.onRequest(async (req, res) => {
    try {
        const { token } = req.query;
        let tokens = 'fyTfgNZAUBA:APA91bGnx9Vp9MwRA4ohVKcNOM8d5s4a4TXdtI0KTSzcWEgZX1WoLGpofcVQFTCdSbnbqObkukzJEXF3cbmvENYD5pr2MrukjqUNy_bclDuM3rJsV5iSU1vWywL2ZVijJ3s0E9GNfRRe'
        var payload = {
            notification: {
              title: 'Urgent action needed!',
              body: 'Urgent action is needed to prevent your account from being disabled!',
              sound: 'default',
                color: '#84B2D9',
                icon: 'ic_notification',
                click_action: 'OPEN_MAIN_ACTIVITY'
            }
          };

          // Set the message as high priority and have it expire after 24 hours.
          var options = {
            priority: 'high',
            timeToLive: 60 * 60 * 24
          };


          console.log('token',token)
        let d = await admin.messaging().sendToDevice(tokens, payload,options);
        return res.status(200).send({ success: d})

    } catch (e) {
        console.info(e)
        return res.status(400).send({ error: 0 })

    }

})

в ответе от функции http я получаю успех (как вы можете видеть здесь)

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

}

и в моем отладчике в консольном журнале я получаю уведомление как хочу enter image description here

но проблема, которую я не получаю push-уведомления, когда приложение закрыто. Я хочу получать уведомления, когда меня нет в приложении.

кроме того, когда я использую для отображения уведомления, когда я получаю любое уведомление

notificationListener = firebase
  .notifications()
  .onNotification(notification => {
    console.log(notification)
    firebase.notifications().displayNotification(this.notification2)
    // Process your notification as required
    console.log(`Recieved notification 2`);
  });

}

чтобы мои данные здесь не отображались

  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',
  });

так что мне нужно сохранить его в состоянии, а затем в заголовке для отображения данных?

...