Сброс Pu sh Уведомления / Регистрация устройства / Идентификатор экземпляра - Обновление приложения через TestFlight или App Store - Облачная система обмена сообщениями Firebase iOS / React Native Firebase - PullRequest
1 голос
/ 18 января 2020

Я провел много исследований по этой проблеме, сначала мои настройки:

Моя проблема довольно простая и прямолинейная, хотя, похоже, я не могу найти четкого способа ее решения.

Я развернул версию 4.2 моего приложения. Firebase Cloud Messaging (FCM) в iOS работает просто модно. Затем я развернул 4.3 в TestFlight, чтобы начать тестирование. Установил 4.3 через TestFlight и FCM перестал работать, уведомлений pu sh нет. Если я удаляю приложение и устанавливаю 4.3 через TestFlight pu sh, уведомления снова работают, устройство регистрируется.

Я также могу воспроизвести эту проблему, обновляя установленную версию моего приложения из последней версии App Store, нет. сюрприз там.

Я знаю, что токен InstanceId / device основан на сборке приложения + устройство, поэтому имеет смысл, что токен изменяется при обновлении приложения, но мой токен при обновлении с 4.2 до 4.3 остается таким же. :

const fcmToken = await firebase.messaging().getToken(); //same whether 4.2 or 4.3

И да firebase.messaging (). GetToken () кэшируется при первоначальном создании.

Итак, я подключен к прослушиванию событий смены токена:

firebase.messaging().onTokenRefresh(async () => {
  console.log('======onTokenRefresh=========');
  AsyncStorage.removeItem(FCM_TOKEN_KEY);
  await getToken();
});

Кажется, это никогда не срабатывает. Я даже добавил кнопку в свое приложение, чтобы попытаться форсировать новый InstanceId и зарегистрироваться в FCM после обновления версии из TestFlight или AppStore, это не помогает:

export async function forceRefresh() {
  console.log('================force a new registration!!!==========');
  AsyncStorage.removeItem(FCM_TOKEN_KEY);
  firebase.messaging().deleteToken();
  firebase.iid().deleteToken();
  registerForPushNotificationsAsync(true);
} 

Нет, не работает .

Итак, мораль этой истории в том, что, когда я обновляю версию своего приложения, мои клиенты, чьи уведомления pu sh работали денди, больше не будут регистрироваться для уведомлений pu sh, когда они обновите свое приложение до следующей версии.

Ссылки, которые могут быть ведущими, которые я изучал:

Интересно при запуске обновления приложения, когда pu sh уведомления будут перестать работать, потому что о В обновлении приложения я вижу два разных токена, возможно, первым из них является APN-токен от Apple :

2020-01-17 18:48:09.371741-0800 native[4462:1287461] -[RNFirebaseMessaging messaging:didReceiveRegistrationToken:] [Line 86] Received new FCM token: eBBgznWj1FU:APA91bF8vTmpkwcojp4oDSKFzlPDp6ylEIe_WGNzu24SKHS6RR-3xPu2-cX-Qyc8rrMIQMvkCJftT9711ll1WdshBWS4iEpZ3XpiPeTynqM-nvDjpAUUUWJpfT5aeo6G_scDsN9iipwI
2020-01-17 18:48:09.378382-0800 native[4462:1287621] 6.15.0 - [Firebase/InstanceID][I-IID014012] Invalidating cached token for 255558254149 (*) due to token is no longer fresh.

Затем чуть позже мой предыдущий токен из предыдущей версии приложения. где загружены рабочие уведомления * pu sh Я вижу работу "токен по умолчанию" в логах:

2020-01-17 18:48:09.987571-0800 native[4462:1287610] 6.15.0 - [Firebase/InstanceID][I-IID014001] Token fetch successful, token: dUY5psWDnkv2td1kB_t6Gs:APA91bEaREBt07CWiEyGvP4YAGjxmVQmF0IcXgef5XcvL5KWrHsqcxZZ8L9PqwGzKTPFGy6cdmuVXSvg6kDQjj-652jt5_jbbKMhUFTcam_-FeBp2vGZvBjaBd4aAOtQf1m48htQ8d6B, authorizedEntity: 255558254149, scope:*
2020-01-17 18:48:09.987764-0800 native[4462:1287461] -[RNFirebaseMessaging messaging:didReceiveRegistrationToken:] [Line 86] Received new FCM token: dUY5psWDnkv2td1kB_t6Gs:APA91bEaREBt07CWiEyGvP4YAGjxmVQmF0IcXgef5XcvL5KWrHsqcxZZ8L9PqwGzKTPFGy6cdmuVXSvg6kDQjj-652jt5_jbbKMhUFTcam_-FeBp2vGZvBjaBd4aAOtQf1m48htQ8d6B
2020-01-17 18:48:09.993088-0800 native[4462:1287610] 6.15.0 - [Firebase/InstanceID][I-IID003010] Successfully fetched default token.
2020-01-17 18:48:09.993755-0800 native[4462:1287610] 6.15.0 - [Firebase/InstanceID][I-IID003008] Got default token dUY5psWDnkv2td1kB_t6Gs:APA91bEaREBt07CWiEyGvP4YAGjxmVQmF0IcXgef5XcvL5KWrHsqcxZZ8L9PqwGzKTPFGy6cdmuVXSvg6kDQjj-652jt5_jbbKMhUFTcam_-FeBp2vGZvBjaBd4aAOtQf1m48htQ8d6B

Как интересно, после удаления текущей версии приложения и установки последней версии (в предыдущем журнале это была версия обновления) мы можем увидеть тот же процесс в обратном порядке, сначала мой текущий токен найден и больше не считается fre sh:

messaging:didReceiveRegistrationToken:] [Line 86] Received new FCM token: dUY5psWDnkv2td1kB_t6Gs:APA91bEaREBt07CWiEyGvP4YAGjxmVQmF0IcXgef5XcvL5KWrHsqcxZZ8L9PqwGzKTPFGy6cdmuVXSvg6kDQjj-652jt5_jbbKMhUFTcam_-FeBp2vGZvBjaBd4aAOtQf1m48htQ8d6B
2020-01-17 19:03:06.651179-0800 native[4475:1291698] 6.15.0 - [Firebase/InstanceID][I-IID014012] Invalidating cached token for 255558254149 (*) due to token is no longer fresh.

Впоследствии новый токен загружается и считается по умолчанию токен и моя новая установка сразу же получает уведомления FCM:

2020-01-17 19:03:07.997209-0800 native[4475:1291564] -[RNFirebaseMessaging messaging:didReceiveRegistrationToken:] [Line 86] Received new FCM token: ebz2ACPpBkg0kGsgs9yF7_:APA91bGErCaPMuLyRk-_BLZXUk8_U6FyxvKHbI0NPgddFWl_-nLZuCc6HbHg8kaLMDJiO7sHFS8THAuV132xgri8uQ9YV4g8zDXJySrKsSTNiDq9HcXpzUQXQlPy8bTaxZ3gyRxyCy3p
2020-01-17 19:03:08.018870-0800 native[4475:1291684] 6.15.0 - [Firebase/InstanceID][I-IID014001] Token fetch successful, token: ebz2ACPpBkg0kGsgs9yF7_:APA91bGErCaPMuLyRk-_BLZXUk8_U6FyxvKHbI0NPgddFWl_-nLZuCc6HbHg8kaLMDJiO7sHFS8THAuV132xgri8uQ9YV4g8zDXJySrKsSTNiDq9HcXpzUQXQlPy8bTaxZ3gyRxyCy3p, authorizedEntity: 255558254149, scope:*
2020-01-17 19:03:08.019018-0800 native[4475:1291684] 6.15.0 - [Firebase/InstanceID][I-IID003010] Successfully fetched default token.
2020-01-17 19:03:08.019065-0800 native[4475:1291684] 6.15.0 - [Firebase/InstanceID][I-IID003008] Got default token ebz2ACPpBkg0kGsgs9yF7_:APA91bGErCaPMuLyRk-_BLZXUk8_U6FyxvKHbI0NPgddFWl_-nLZuCc6HbHg8kaLMDJiO7sHFS8THAuV132xgri8uQ9YV4g8zDXJySrKsSTNiDq9HcXpzUQXQlPy8bTaxZ3gyRxyCy3p

Только что нашел это заявление о заинтересованности в журналах:

Не установлен токен устройства APNS перед извлечением токена FCM для идентификатора отправителя '255558254149'. Уведомления на этот токен FCM не будут доставляться через APNS. Обязательно повторно получите токен FCM после установки токена устройства APNS.

Трудно поверить, что это происходит так последовательно, но безусловно, имеет место, любая помощь будет принята с благодарностью.

Ответы [ 2 ]

1 голос
/ 28 февраля 2020

Я потратил много времени, прежде чем нашел решение.

Итак, если вы звоните firebase.iid().delete() в iOS, вам необходимо зарегистрировать новый токен в APN. Я не видел этого в документации по нативной firebase, просто нашел в типах lib

await firebase.messaging().ios.registerForRemoteNotifications()

Пожалуйста, вызывайте этот метод после генерации нового токена

1 голос
/ 18 января 2020

Ну, в конце концов, это было состояние гонки, я нашел отличный намек здесь

Похоже, с реагирующим-firebase Firebase.messaging (). GetToken () будет не всегда возвращать последний токен - используйте вместо него onTokenRefre sh. Мое приложение сохраняло и использовало старый токен, но не обновляло новый - очень маленькое состояние гонки.

Просто используйте Firebase.messaging.onTokenRefre sh () в качестве источника правды, чтобы избежать проблем с переносом приложений , Также, чтобы быть уверенным, что вы получаете токен, который работает. Возможно, вы захотите удалить свой токен в миграции, такой как этот, с помощью v4 -> await Firebase.iid (). DeleteToken () или v5 (Firebase.messaging (). DeleteToken (). Затем положитесь на TokenRefre sh, чтобы отправить вам новый для отправки на ваш сервер.

Теперь firebase.messaging().deleteToken(), упомянутый в приведенной выше цитате, недостаточно «хорош», чтобы вызвать tokenRefre sh при обновлении приложения из TestFlight или Apple App Store.

Я должен был назвать асинхронный (все, что касается этой проблемы - это практическое правило):

firebase.iid().delete();

Этот React Native Firebase метод API удаляет InstanceId, который в действительности используется для токена Firebase Cloud Messaging (FCM).

Это вызовет onTokenRefre sh. Поэтому я проверял версию и номер сборки приложения и сохранял их. это в пользовательских данных приложения (NSDefaults для iOS), я проверяю, существует ли эта версия и сборка, если это не так, я "flu sh" токен устройства. Таким образом, это происходит только один раз.

собираюсь добавить мой код в надежде, что он поможет другим в этой проблеме, по сути, благодаря моим исследованиям, использующим React Native Firebase 5.x, это то, что вам нужно сделать, чтобы обеспечить бесперебойную регистрацию уведомлений pu sh с помощью Firebase Cloud Messaging в приложении iOS обновления:

В вашем приложении. js добавьте следующее:

   configureFirebaseCloudMessaging = async () => {
    //wire up Firebase Cloud Messaging onTokenRefresh listener

    this.fcmOnTokenRefreshUnsubscribe = await firebase.messaging().onTokenRefresh(async fcmToken => {
      console.log('*********************** onTokenRefresh *****************');
      //this is callBack called typically sometime in the future but can be call with app loaded but user not logged in
      //check for that case and exit if there is no accessToken to call APIs
      const accessToken = await AsyncStorage.getItem('access-token');
      if (!accessToken) {
        console.log('************** user is not logged in exit onTokenRefresh do not register device ************');
        return;
      }
      await this.registerDevice(fcmToken, BASE_URL);
      await AsyncStorage.setItem('fcmToken', fcmToken);
      firebase.crashlytics().log(`flushed new fcmToken: ${fcmToken}`);
      console.log('***************** success  account updated with latest token **************');
    });

    //Firebase Cloud Messaging time
    await this.requestPushPermission();
    await this.checkFlushv();
  }

  checkFlushv = async () => {
    let FLUSHV = `${DeviceInfo.getVersion()}-build-${DeviceInfo.getBuildNumber()}`;

    const flush = await AsyncStorage.getItem(FLUSHV);
    console.log('======= checking FLUSHV=========', flush);
    if (flush) {
      console.log('***** device token already been flushed ******');
      return;
    }

    const accessToken = await AsyncStorage.getItem('access-token');
    console.log('flushy access token:', accessToken);
    if (!accessToken) {
      console.log('******** user is not logged in do not flush ************');
      return;
    }

    //force push notifications, this will fire onTokenRefresh callback
    await firebase.iid().delete();

    //iterate all keys and remove other builds to keep tidy and TestFlighters possibly going up and back down build versions for testing
    const keys = await AsyncStorage.getAllKeys();
    const buildKeys = keys.filter(key => {
      return key.indexOf('build') !== -1;
    });
    await AsyncStorage.multiRemove(buildKeys);

    //add current build key so no more flushy
    await AsyncStorage.setItem(FLUSHV, FLUSHV);
    console.log(`=================FLUSHV clear: ${FLUSHV}===================`)
  }

  registerDevice = async (token, baseUrl) => {
    console.log(`******** registerDevice token: ${token}, baseUrl: ${baseUrl}`);
    let data = {
      device: 'firebase',
      token: token
    }

    //register token with  account
    axios.post(`${baseUrl}/myapi/register_device`, data)
      .then(response => {
        return {}
      })
      .catch(err => {
        console.log(err)
        return {}
      })
  }

А затем в вашем приложении. js:

  async componentDidUpdate() {
    //a new version of the app could be loaded post/after App.componentDidMount
    await this.checkFlushv();
  }

  async componentWillUnmount() {
    console.log('app componentWillUnmount');
    this.fcmOnTokenRefreshUnsubscribe(); //not really sure unsubcribe is needed but keeping tidy
    this.fcmOnTokenRefreshUnsubscribe = null;
  }

  async componentDidMount() {
    await this.configureFirebaseCloudMessaging();
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...