Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Messaging getToken() always returns initialToken #1510

Closed
britianoates opened this issue Sep 20, 2018 · 40 comments · Fixed by #1805
Closed

Messaging getToken() always returns initialToken #1510

britianoates opened this issue Sep 20, 2018 · 40 comments · Fixed by #1805
Labels
platform: ios plugin: messaging FCM only - ( messaging() ) - do not use for Notifications type: bug New bug report

Comments

@britianoates
Copy link

Issue

messaging.getToken() keeps returning the first token, even if the firebaseId has been deleted and a new token generated.

To Reproduce. In a onTokenRefresh callback, log out the parameter token and a messaging.getToken and compare. No matter how many times you delete the instanceId generating new tokens you'll always receive the first token.

Environment

  1. Application Target Platform:

Both

  1. Development Operating System:

mac High Sierra

  1. Build Tools:

xcode 9.4, Android Studio 28

  1. React Native version:

    "react-native": "0.55.4",

  2. React Native Firebase Version:

    "react-native-firebase": "^4.0.3",

  3. Firebase Module:

firebase-core:12.0.1
firebase-analytics:12.0.1
firebase-messaging:12.0.1

  1. Are you using typescript?

no

@britianoates
Copy link
Author

@Salakar Salakar added type: bug New bug report help: needs-tests Needs a test case adding to the project tests. platform: ios plugin: messaging FCM only - ( messaging() ) - do not use for Notifications labels Sep 20, 2018
@smathson
Copy link

@britianoates If I read this correctly it would only impact the case where the token changed during a single app instance, correct? Like if you manually delete the firebaseId for example. Is that something you do when a user signs out?

We are trying to chase down an issue on iOS where an FCMToken seems to stop working over the course of a couple days and I'm trying to determine if token refresh has anything to do with it. According to the Firebase docs a token refresh on it's own should be a rare event.

@britianoates
Copy link
Author

We had many users not seeing the notifications we were sending. It was difficult to track down what percentage or when notifications stopped arriving. What you are seeing sounds similar to what we just dealt with in prod. To fix our users we've released a version of the app that calls RequestPermission every app opening to make sure the APNS and fcmToken remain synced.

Calling to delete the firebase instanceId has been the only way we were able to recreate the failure to receive notifications. We do not delete the token as a part of normal app usage.

@smathson
Copy link

Interesting. Does it seem like that fixed the issue for you guys?

That sounds very similar to what we're seeing. We didn't notice this problem before our last release and in that release we added code to try and capture analytics events for how many users were denying notification permissions that had an early return if they had already enabled permissions. We also only request permission after a user signs in for the first time. Previously we had been calling requestPermission on every authenticated app opening.

@britianoates
Copy link
Author

We have not been in production long enough to be confident our fix covers all use cases. It did cover all scenarios we were able to fake using deleteToken on a dev screen, and the one device from prod we had access to.

Sounds like your solution was the opposite of ours. We only registered during the first run, and then the APNS and fcmToken seems to grow stale and we didn't have a mechanism to resync them. Our fix calls requestPermission on app start (Does not open modal, but does trigger a registration method. See my other ticket.)

@jcharbo
Copy link

jcharbo commented Oct 3, 2018

I'm seeing the same problem. Users that have been receiving notifications for weeks suddenly stop receiving them. I can have them open the app, get the token returned by firebase, put that token into the firebase console and send a message. The console reports success but the user never receives the push. It appears that somehow the token is invalid yet firebase doesn't see it as invalid. This is a very serious problem as we have no way of knowing which users simply never receive their push notifications.

@smathson
Copy link

smathson commented Oct 3, 2018

@jcharbo Are you also attempting to only call Firebase.requestPermissions() on a limited basis in your app?

@duongntb94
Copy link

I have the same issue as britianoates. messenging().getToken() only returns the initialToken. It only happens on iOS. On Android, it works fine, when the token change, messaging().getToken() return the new token.

@BrendonSled
Copy link

This can be really easily reproduced. On iOS:

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

@kholiavko-roman
Copy link

kholiavko-roman commented Oct 30, 2018

So, guys, what is the solution of the problem ? Just remove


as @britianoates noted above? Is it right ?

@stale
Copy link

stale bot commented Nov 27, 2018

Hello 👋, this issue has been automatically marked as stale because it has not had activity for quite some time. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the Type: Stale Issue has become stale - automatically added by Stale bot label Nov 27, 2018
@mskv
Copy link

mskv commented Nov 29, 2018

Has anyone experimented with adjusting the implementation of RNFirebaseMessaging.m?

Is this issue on the roadmap anytime soon? Is some more reproduction instructions or experimenting needed from the library users?

@stale stale bot removed the Type: Stale Issue has become stale - automatically added by Stale bot label Nov 29, 2018
@lkwjohn
Copy link

lkwjohn commented Dec 4, 2018

This can be really easily reproduced. On iOS:

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

How does the firebase.messaging().deleteToken() work? I'm getting the error of firebase.messaging().deleteToken() is unsupported by the native Firebase SDKs

@henrymoulton
Copy link

henrymoulton commented Dec 14, 2018

Can confirm that we're seeing this type of behaviour described above:

We are trying to chase down an issue on iOS where an FCMToken seems to stop working over the course of a couple days and I'm trying to determine if token refresh has anything to do with it.

We had many users not seeing the notifications we were sending. It was difficult to track down what percentage or when notifications stopped arriving.

I can have them open the app, get the token returned by firebase, put that token into the firebase console and send a message. The console reports success but the user never receives the push. It appears that somehow the token is invalid yet firebase doesn't see it as invalid. This is a very serious problem as we have no way of knowing which users simply never receive their push notifications.

I'm checking that tokens are part of topics using this API call: https://iid.googleapis.com/iid/info/<FCM_TOKEN>?details=true&Authorizaton=<SERVER_KEY>

And it seems they are, we're looking into the solution that @britianoates described

To fix our users we've released a version of the app that calls RequestPermission every app opening to make sure the APNS and fcmToken remain synced.

@smathson did you solve this issue?

@liokm
Copy link

liokm commented Dec 20, 2018

Any news on this? I am facing similar issue on iOS where a freshly retrieved FCM token is claimed to be not registered from FCM server when sending notification.

@kholiavko-roman
Copy link

@liokm Are you get this error only after removing token and getting new one ?
I also have the same problem right now in production.

@henrymoulton
Copy link

henrymoulton commented Dec 21, 2018

@liokm this bug report was for "react-native-firebase": "^4.0.3", when I joined the project it was on 4.3.x I didn't realise how behind the dependencies of the project I'm on were so trying out the latest 5.x.x release now. Will report back (we've moved crucial notifications to SMS in the meantime using Twilio).

@liokm
Copy link

liokm commented Dec 22, 2018

@kholiavko-roman Actually my issue was a mix of two problems, one was that my app was transferred to another account and thus the team id and APNS key were invalid in FCM console and needed to be updated, otherwise "not registered" error is reported. Another problem is still waiting for feedback of logs. Have you tried to always requestPermission at start time anyway?

@kholiavko-roman
Copy link

kholiavko-roman commented Dec 22, 2018

@liokm Yes, I do requestPermission on each time when app starting. And also I have onTokenRefreshListener in my app.
With my FCM key also all is okay, I rechecked this things.
And one more thing - I have the same problem with unregistered tokens on android.

@lisichka999
Copy link

@kholiavko-roman, how did you implement onTokenRefreshListener in you App? I did not find any API for this in react-native-firebase package. Thanks

@kholiavko-roman
Copy link

@lisichka999
It calls onTokenRefresh

componentDidMount() {
 this.onRefreshToken = firebase
      .messaging()
      .onTokenRefresh(this.props.setDeviceId);
}

componentWillUnmount() {
    if (this.onRefreshToken) {
      this.onRefreshToken();
    }
  }

@Nerogee
Copy link

Nerogee commented May 31, 2019

I'm having the same issue here. firebase 5.4.0. platform: iOS
I managed to get a new token by deleting the old one. I called firebase.messaging().deleteToken() before firebase.messaging().getToken();. And it did return me a fresh token. But that token turns out to be invalid and give me error NotRegistered during pushing notification. Any solution?

@kashmiry
Copy link

I am having the same issue
on RNFB 6.2.0 iOS
I can get the first token, but after deleting the token I keep getting the initial token.

@mtieltjes
Copy link

Leaving these references for anyone experiencing the same issue:
#3714
firebase/firebase-ios-sdk#6433

@Stevemoretz
Copy link

What happened at the end???
I still can't get a new token on ios.

@britianoates
Copy link
Author

It's been awhile. I ended up working around this by saving the token after an earlier call on my side rather than calling for it since this is broken.

@Stevemoretz
Copy link

@britianoates

Would you please explain how you achieved what you're describing with some code.

@Stevemoretz
Copy link

I found the solution.

        messaging()
            .deleteToken(undefined,'*')
            .then(() => {
                RNRestart.Restart();

Use this to delete the token then restart the app with https://www.npmjs.com/package/react-native-restart now you're sure you get a new token :) I haven't tested this on android so I don't know if android also needs this if android doesn't have this problem just put a little if statement to do this only for ios.

@SebastianGrzymala
Copy link

It was enough for me to solve the problem (works on iOS & Android):

messaging().deleteToken(undefined,'*');

@mikehardy
Copy link
Collaborator

I'm going to reopen this as I think we have either a documentation issue or we need to alter the code to specify the asterisk as the default. Either way I appreciate the reports of what's working posted here, thanks

@mikehardy mikehardy reopened this Jan 27, 2021
@mikehardy mikehardy added the Workflow: Needs Review Pending feedback or review from a maintainer. label Jan 27, 2021
@mikehardy
Copy link
Collaborator

v12.x.x coming up here will have this working correct on both platforms it seems - closing this as it will be backed by an automated test in our test suite. Use the scoped token workaround documented above until on v12+

Thanks!

@mikehardy mikehardy added Resolution: Solution Provided and removed help: needs-tests Needs a test case adding to the project tests. Workflow: Needs Review Pending feedback or review from a maintainer. labels May 14, 2021
@rdsedmundo
Copy link

rdsedmundo commented May 29, 2021

I'm using v12 and deleteToken simply has no effect on iOS.

I call it with await and it yields null, then I proceed to call getToken again right after, and the same token is returned.

Also did another test, called deleteToken, then tried to send a push notification to the "invalidated" token, and it unexpectedly still works.

The deleteToken(undefined, '*') workaround doesn't do it either.

On Android, it works perfectly: a new token is generated, and also the previous one is invalidated (trying to send a message to it again from the REST API returns a NotRegisteredError). With the exact same JS code.

@mikehardy
Copy link
Collaborator

And yet, there is an actual test I have verified (while fixing up the test, via console.log statements) appeared to work for me?

This runs every commit

describe('deleteToken()', function () {
it('generate a new token after deleting', async function () {
const token1 = await firebase.messaging().getToken();
should.exist(token1);
await firebase.messaging().deleteToken();
const token2 = await firebase.messaging().getToken();
should.exist(token2);
token1.should.not.eql(token2);
});
});

@milule
Copy link

milule commented Jun 21, 2021

@mikehardy I have a same issue like @rdsedmundo. When i call messaging().deleteToken() and then i continue call getToken() after, the new token and previous token are same. i use "@react-native-firebase/messaging": "^12.1.0". I have test on debug and production environment

@mikehardy
Copy link
Collaborator

@milule can you confirm whether you were on simulator or real device? We think this actually may still be an issue from separate testing (contrary to my statement above, sorry) but only on real devices. We have not narrowed it down yet.

@mikehardy mikehardy reopened this Jun 21, 2021
@stale
Copy link

stale bot commented Jul 21, 2021

Hello 👋, to help manage issues we automatically close stale issues.
This issue has been automatically marked as stale because it has not had activity for quite some time. Has this issue been fixed, or does it still require the community's attention?

This issue will be closed in 15 days if no further activity occurs.
Thank you for your contributions.

@stale stale bot added the Type: Stale Issue has become stale - automatically added by Stale bot label Jul 21, 2021
@edulpn
Copy link

edulpn commented Jul 21, 2021

We are getting the exact symptoms described above on Android, both simulator and real device. Both getToken and onTokenRefresh give the same previous token after deleteToken was called.

@stale stale bot removed the Type: Stale Issue has become stale - automatically added by Stale bot label Jul 21, 2021
@mikehardy
Copy link
Collaborator

The failures on android are contrary to reported experience above, and my personal experience. When used properly (they are async, so you have to await...) it works fine on android we think. There still may a problem on iOS but as mentioned we have not narrowed it down.

The best way to move this forward is to use either firebase-ios-sdk or firebase-android-sdk "quickstart" projects to reproduce this (or not) with the native SDKs so we may determine where the issue is.

https://github.com/firebase/quickstart-android/tree/master/messaging
https://github.com/firebase/quickstart-ios/tree/master/messaging

They both are ready to go out of the box I think, or maybe need your google services plist/json files but otherwise ready for a quick reproduction

@rskapadiadev
Copy link

This below snippet fixed my issue

export const getFBRefreshToken = () => {
  return messaging()
    .deleteToken(undefined, '*')
    .then(async () => {
      const newToken = await messaging().getToken();
      return newToken;
    });
};

@mikehardy
Copy link
Collaborator

Firebase-ios-sdk 8.6.0 included in react-native-firebase 12.7.0 should have another underlying fix for this so that deleteToken really works?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
platform: ios plugin: messaging FCM only - ( messaging() ) - do not use for Notifications type: bug New bug report
Projects
None yet
Development

Successfully merging a pull request may close this issue.