Android前台推送通知未显示

6

我在安卓和iPhone上使用react-native-fcm进行远程通知。

react-native-fcm

在安卓前台,我无法在通知栏中获取远程通知。

在后台模式下,我能够成功接收到通知,但是在前台模式下却不行。

Android Manifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.nusape">

    <application>

        <receiver android:name="com.evollu.react.fcm.FIRLocalMessagingPublisher"/>
        <receiver android:enabled="true" android:exported="true"  android:name="com.evollu.react.fcm.FIRSystemBootEventReceiver">
            <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="@mipmap/ic_launcher"/>
        <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="my_default_channel"/>

        <service android:name="com.evollu.react.fcm.MessagingService" android:enabled="true" android:exported="true">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>

        <service android:name="com.evollu.react.fcm.InstanceIdService" android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
            </intent-filter>
        </service>



       <activity android:launchMode="singleTop" android:configChanges="keyboard|keyboardHidden|orientation|screenSize" android:windowSoftInputMode="adjustResize">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <intent-filter>
                <action android:name="fcm.ACTION.HELLO" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

        </activity>
        <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    </application>

</manifest>

App.js

async componentDidMount() {
// create NotificationChannel for future use!
    FCM.createNotificationChannel({
      id: 'my_default_channel',
      name: 'Default',
      description: 'used for example',
      priority: 'high'
    });

    // initially user get InitialNotification frim the app if any pending
    FCM.getInitialNotification().then(notif => {
      console.log("getInitialNotification Notification : => ", notif);

      // if notif.targetScreen is details screen then it will redirect to details screen directly!
      if (notif && notif.targetScreen === "detail") {
        setTimeout(() => {
          this.props.navigation.navigate("Detail");
        }, 500);
      }
    });

    // added notification listener for getting any notification called below function then
    this.notificationListener =  FCM.on(FCMEvent.Notification, async (notif) =>  {
      console.log("FCMEvent.Notification Notification : => ", notif);

      if (Platform.OS === 'ios' && notif._notificationType === NotificationType.WillPresent && !notif.local_notification) {
        notif.finish(WillPresentNotificationResult.All);
        return;
      }

      // if user tap to notification bar then open app then below condition will follow up and redirect to details screen!
      if (notif.opened_from_tray) {
        if (notif.targetScreen === 'detail') {
          setTimeout(() => {
            navigation.navigate('Detail')
          }, 500)
        }
        setTimeout(() => {
          alert(`User tapped notification\n${JSON.stringify(notif)}`)
        }, 500)
      }

      // check whether app is in background or foreground for generate notification
     if (AppState.currentState !== 'background'){
        this.showLocalNotification(notif);


    });

    // getting user permission for sending notification or not ?
    try {
      let result = await FCM.requestPermissions({
        badge: true,
        sound: true,
        alert: true
      });
      console.log("Notification requestPermissions : => ", result)
    } catch (e) {
      console.error(e);
    }

    // Generating token for particular user wise send notification
    FCM.getFCMToken().then(token => {
      FCM.subscribeToTopic("channelToTopic");
      console.log("Notification token : => ", token);
      this.setState({ token: token || "" });
    });

    // Get APNSTOKEN for only ios
    if (Platform.OS === "ios") {
      FCM.getAPNSToken().then(token => {
        console.log("APNS TOKEN (getFCMToken)", token);
      });
    }
  }

  // show notification when app is in foreground and getting any new notification
  showLocalNotification = (notif) => {
    FCM.presentLocalNotification({
      channel: 'my_default_channel',
      id: new Date().valueOf().toString(),
      title: notif.fcm.title,
      body: notif.fcm.body,
      priority: "high",
      badge: 1,
      number: 1,
      ticker: "My Notification Ticker",
      auto_cancel: true,
      big_text: "Show when notification is expanded",
      sub_text: "This is a subText",
      wake_screen: true,
      group: "group",
      icon: "ic_launcher",
      ongoing: true,
      my_custom_data: "my_custom_field_value",
      lights: true,
      show_in_foreground: true
    });
  };

我遭遇了这个问题已经两个月了,但一直没有找到解决方案。虽然我尝试了很多方法来解决它,但最终都没有成功。


这里有人得到了完美的解决方案吗?而不是发送本地通知? - Hardik Virani
3个回答

7
根据官方 Github 上的资料,react-native-fcm 库已经过时。您可以使用 react-native-firebase 生成通知。我在大约两个小时内就让 Android 收到了通知。如果您需要代码,我可以分享给您。祝好运。
更新 - 很抱歉因为我的办公室帐户问题,我不能及时回答您的问题。
这是我用于显示 Android 前台通知的代码。
firebase.messaging()
        .subscribeToTopic(this.state.user.user_name)
        .then(response => console.log('response from FCM TOPIC' + response))
        .catch(error =>  console.log('error from FCM TOPIC'+ error));

        this.notificationListener = firebase.notifications().onNotification(notification => {
            let notificationMessage = notification._android._notification._data.action;
            let recordId = notification._android._notification._data.recordID;

            let { title, body } = notification;
            //  console.log('ttttt', notification)
            // notification.android.setAutoCancel(false)
            console.log(title, body, notificationMessage, recordId);


            const channelId = new firebase.notifications.Android.Channel(
                'Default',
                'Default',
                firebase.notifications.Android.Importance.High
            );
            firebase.notifications().android.createChannel(channelId);

            let notification_to_be_displayed = new firebase.notifications.Notification({
                data: notification._android._notification._data,
                sound: 'default',
                show_in_foreground: true,
                title: notification.title,
                body: notification.body,
            });

            if (Platform.OS == 'android') {
                notification_to_be_displayed.android
                    .setPriority(firebase.notifications.Android.Priority.High)
                    .android.setChannelId('Default')
                    .android.setVibrate(1000);
            }
            console.log('FOREGROUND NOTIFICATION LISTENER: \n', notification_to_be_displayed);

            firebase.notifications().displayNotification(notification_to_be_displayed);
        });


我有一个问题,我正在开发两个应用程序,第一个是用户应用程序,第二个是供应商应用程序,在用户应用程序中,我编写了一些函数来发送订单并将其保存到实时数据库Firebase中,在第二个应用程序中,我只需使用监听器从数据库中检索数据以获取新订单作为实时数据而无需刷新应用程序,所以当我从用户应用程序向Firebase发送订单时,我想在第二个应用程序中显示通知?如何处理这些? - DevAS
你是否正在使用Firebase作为后端数据库?如果是的话,那么你必须在第一个应用程序中创建一个函数,该函数将向Firebase发送触发器以在第二个应用程序中生成通知。如果你正在使用任何传统数据库(例如:Laravel等),那么你必须在你的数据库中创建一个函数,该函数将向第二个应用程序发送通知。 - Usman Kazmi
你可以在这里查看更多详情: https://stackoverflow.com/questions/56140314/how-to-communicate-between-two-apps-using-the-same-firebase-database-in-react-na - DevAS

3
根据此处列出的库问题,您可以尝试以下两个方法:
  1. 在远程通知中的 data 属性中传递 show_in_foreground

  2. Android 仅在应用程序状态为“已杀死”或“后台”时显示通知。要在应用程序前台显示通知,您需要显示一个 本地通知

示例代码:

FCM.on(FCMEvent.Notification, notif => {
    if (!notif.opened_from_tray) {
        showLocalNotification();
    }
});

showLocalNotification() {
    FCM.presentLocalNotification({
      id: new Date().valueOf().toString(),         // (optional for instant notification)
      title: "Test Notification with action",      // as FCM payload
      body: "Force touch to reply",                // as FCM payload (required)
      show_in_foreground: true                     // notification when app is in foreground (local & remote)
    });
  }

完整的代码在这里


我有一个问题,我正在开发两个应用程序,第一个是用户应用程序,第二个是供应商应用程序,在用户应用程序中,我编写了一些函数来发送订单并将其保存到实时数据库Firebase中,在第二个应用程序中,我只需使用监听器从数据库中检索数据以获取新订单作为实时数据而无需刷新应用程序,所以当我从用户应用程序发送订单到Firebase时,我想在第二个应用程序中显示通知?如何处理这些? - DevAS
你需要查看上游通知来解决这个问题。 - Firu

2
你正在测试哪个API级别?Android API 26及以上版本需要创建通道才能在前台接收通知。请阅读这篇文章获取更多信息。 react-native-fcm已更新,包括通道功能,请参考这里。虽然该库不再维护,但一个很好的替代方案是react-native-firebase

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接