使用 FCM 发送通知时,在 ios 上为单个事件获取双重通知弹出窗口

Getting double notification popup for single event on ios when sending notification using FCM

问题描述::

我正在开发 React Native 应用程序并使用 React Native firebase 消息服务进行推送通知。我在 IOS 平台上遇到问题。我收到单个事件的双重通知弹出窗口。

生成案例的步骤::

  1. 安装应用程序后,如果我登录并通过 FCM 发送通知,我只会收到一个弹出窗口。在此之后我注销并再次登录,这次我得到了一个通知的双弹出窗口。在这种情况下,我不会从后台清除应用程序。

  2. 如果我在每次注销后从后台清除一个应用程序,我只收到一个针对单个事件的弹出窗口。

  3. 当我从应用程序注销并强制从 FCM 发送通知时,我在应用程序初始化屏幕(登录屏幕)上出现双弹出窗口。

我在用户登录时生成一个新的设备令牌并将此令牌保存在本地存储中,我们在注销时清除本地存储数据。

代码::

async mountDashboard() {
    const enabled = await firebase.messaging().hasPermission();
    if (enabled) {
        const fcmToken = await firebase.messaging().getToken();
        await AsyncStorage.setItem(LocalStorageKeys.DEVICE_TOKEN, fcmToken);
        if (fcmToken) {
            //--- here we are saving our token and sendind data to API
        }
    }

    // in Foreground
    this.notificationListener = firebase.notifications().onNotification((notification) => {
        new RegisterLocalNotification(notification);
    });

    // App in Foreground and background
    let notificationHandler = new NotificationsHandler();
    this.notificationOpenedListener = firebase.notifications().onNotificationOpened((notificationOpen) => {
        notificationHandler.handleNotification(notificationOpen.notification);
    });

    // app close notification handler
    AppCloseNotificationHandler.getInstance().handleNotification();

}

componentDidMount() {
    this.mountDashboard();
}

环境::

二进制文件:

npm 包:

npm 全局包:

当组件将被卸载时,您必须取消订阅您的侦听器。如果您不这样做,您将订阅两个听众。

componentWillUnmount() {
    this.notificationListener(); // it's unsubscribing your listener
}

确保通过后端发送此负载,我使用的是 firebase admin SDK。 这将禁用 Notification By OS 并触发本地通知。我正在使用这个包进行本地通知 https://github.com/zo0r/react-native-push-notification

async function sendPushNotification(message) {

try {
    await admin.messaging().sendToDevice(
        ['dCk27uEySymSdP_vA1C_QI:APA91bEZNyipZDjTLq0jrGnD0qcpKH2y3oTYg3GMgT0pSENNlJEiymOYXvxvnqTFtQaidDLt5KUgp4oDZsfLsQvfiVkL7m1bpMjekHsm-7x1ZDju4TYUMUZeUgYb0CyPwMhdr9RyzA1v'],
        {
            data: {
                owner: 'a',
                user: 'a',
            },
        },
        {
            // Required for background/quit data-only messages on iOS
            contentAvailable: true,
            // Required for background/quit data-only messages on Android
            priority: 'high',
        },
    );

    console.log('A');

}catch(e) {
    console.log('Gagal mengirim pesan');
}

}

这是我在 App.js 中用于收听通知的代码

RNFirebase.onMessage(RNFirebaseOnMessageHandler); RNFirebase.setBackgroundMessageHandler(RNFirebaseOnMessageHandler);

在处理程序中,我使用这个

PushNotification.createChannel(
    {
      channelId: CHANNEL_ID,
      channelName: CHANNEL_NAME,
      channelDescription: CHANNEL_DESCRIPTION,
      soundName: CHANNEL_SOUND,
      importance: CHANNEL_IMPORTANCE,
      vibrate: CHANNEL_VIBRATE,
    },
    (created) => console.log(`createChannel returned '${created}'`), // (optional) callback returns whether the channel was created, false means it already existed.
  );
  PushNotification.localNotification({
    channelId: CHANNEL_ID,
    // @todo get ticker value from data payload
    ticker: 'CreateOrderLandingScreen',
    showWhen: true,
    autoCancel: true,
    largeIcon: CHANNEL_LARGE_ICON,
    smallIcon: CHANNEL_SMALL_ICON,
    bigText: 'aaaaa',
    subText: CHANNEL_SUB_TEXT,
    color: Colors.RED,
    vibrate: true,
    vibration: 300,
    priority: 'high',
    visibility: 'private',
    invokeApp: true,
    alertAction: 'view',
    id: 0,
    title:'aa',
    message: 'aaaa',
    userInfo: {},
    playSound: false,
    soundName: 'default',
  });