Grunch
Grunch

Reputation: 99

react-native-fcm token refresh when app is updated

I am using react-native-fcm component in my RN app for push notifications. It is working perfect but I notice an issue that is driving me crazy, when we release a new version on play store and the app is updated the token expires, we have already saved the old token and we send notifications to that fcm token, so users stops receiving notifications.

If the user log out and log in again I get the new token but of course I can't force to my users to do that, in the component examples I found a refresh token event but it's not working, do you know why the event is not receiving the new token when it refresh? What I am doing wrong? Thanks.

Here is my code (I deleted some parts for readability):

import React, { Component } from 'react';
import { ScrollView, View, Text, Linking, TouchableOpacity, AppState } from 'react-native';
import { connect } from 'react-redux';
import FCM, { FCMEvent } from 'react-native-fcm';
import { getTopNotification, updateUser } from '../api';
import { topNotificationChanged, logOut } from '../actions';

class Home extends Component {
  constructor() {
    super();
    this.onLogOutPress.bind(this);
  }

  state = { topNotificationLink: '', appState: AppState.currentState };

  componentDidMount() {
    AppState.addEventListener('change', this.handleAppStateChange);
    this.refreshTokenListener = FCM.on(FCMEvent.RefreshToken, fcmToken => {
      updateUser(this.props.user.id, this.props.user.token, { fcmToken });
    });
  }

  componentWillUnmount() {
    AppState.removeEventListener('change', this.handleAppStateChange);
    this.refreshTokenListener.remove();
  }

  handleAppStateChange = (nextAppState) => {
    if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
      this.onFocus();
    }
    this.setState({ appState: nextAppState });
  }

  render() {
    return (
      <ScrollView>
        {this.renderTopNotification()}
        {this.renderMenuOptions()}
      </ScrollView>
    );
  }
}

const mapStateToProps = state => {
  return {
    user: state.auth.user,
    lang: state.auth.lang,
    topNotificationText: state.main.topNotificationText
  };
};

export default connect(mapStateToProps, { topNotificationChanged, logOut })(Home);

Upvotes: 6

Views: 6221

Answers (2)

kyounghwan01
kyounghwan01

Reputation: 91

const oldToken = await firebase.messaging().getToken();
await firebase.messaging().deleteToken();
const newToken = await firebase.messaging().getToken();
if (oldToken === newToken) {
    console.error('Token has not been refreshed');
} 

Upvotes: 2

Anil Kashyap
Anil Kashyap

Reputation: 71

import firebase from 'react-native-firebase';
import { RemoteMessage } from 'react-native-firebase';    

componentDidMount() {
    this.checkPermission();
    this.onTokenRefreshListener = firebase.messaging().onTokenRefresh(fcmToken => {
      // Process your token as required
      console.log("Updated Token=" + fcmToken);
    });
    this.messageListener = firebase.messaging().onMessage((message) => {
      // Process your message as required
    });

  }
  componentWillUnmount() {
    this.onTokenRefreshListener();
    this.messageListener();
  }
async checkPermission() {
    const enabled = await firebase.messaging().hasPermission();
    console.log("checkPermission=" + enabled);
    if (enabled) {
      // this.getFCMToken();
      // testTocken();
      let fcmToken = await AsyncStorage.getItem('fcmToken', "");
      console.log("getToken=" + enabled);

      if (!fcmToken) {
        fcmToken = await firebase.messaging().getToken();
        alert(fcmToken);
        if (fcmToken) {
          // user has a device token
          await AsyncStorage.setItem('fcmToken', fcmToken);
        }
      }
    } else {
      this.requestPermission();
    }
  }

  async requestPermission() {
    try {
      await firebase.messaging().requestPermission();
      // User has authorised
      // this.getFCMToken();
      let fcmToken = await AsyncStorage.getItem('fcmToken', "");
      console.log("getToken=" + enabled);

      if (!fcmToken) {
        fcmToken = await firebase.messaging().getToken();
        alert(fcmToken);
        if (fcmToken) {
          // user has a device token
          await AsyncStorage.setItem('fcmToken', fcmToken);
        }
      }
    } catch (error) {
      // User has rejected permissions
      console.log('permission rejected');
    }
  }

Upvotes: 1

Related Questions