Xamarin.Firebase.Messaging - Some Android devices stop receiving notifications
Describe your Issue
I've asked this question a couple of places, and I've yet to get any kind of real answer to it.
I have a Xamarin Forms application where we're using Azure Notification Hub to send messages to both Android and iOS devices.
Whenever someone logs into the application a record is created (or updated) in our database for that device. Various information about that device is stored: who it belongs to, installation id, token, etc, and we register that device with Azure.
However, for some reason, some Android devices will stop receiving notifications. Sometimes this is immediate. That is, right after the app is installed and the device is registered with the hub, it can't receive messages. Other times it could take up to 24 hours or so, but a device that was receiving messages will suddenly stop.
If I use the Firebase console to send a message to the broken device the message is never received. If I use cURL I get a "not registered" error.
iOS never seems to have an issue.
I'm unsure how to proceed. It's almost as if the FCM token is invalid at some point. From what I've read the only time it really should become invalid is if the app is newly installed, the data was cleared, or the device was restored. But this invalidated token seems to happen immediately after install or after a day or so of previously receiving notifications without issue.
If this is the case, is there some way I'm supposed to be aware of the invalidated token? I can use FirebaseMessaging.Instance.GetToken() to get the latest token and compare it to what we have stored in our database, but that seems like a hack, right? Shouldn't OnNewToken() fire because the token changed? I shouldn't have to explicitly go out and check that the token was updated, right?
I did see in the Android FCM tutorial where they showed how to get the latest token, but it didn't really explain why I'd want to do this or when. If I am supposed to check for token changes, what's the best practices for handling this? I suppose I could check it in the OnCreate() method of MainActivity.
Full disclosure, I did realize just now that my Xamarin.Firebase.Messaging is very out of date. I was previously unable to update it for some other reasons, and the version I have been using is 71.1740.0. While I can't rule out an out of date nuget package as a possible cause of my issue, I feel like I'd have run into more documented cases of this happening if there was something like that wrong with the previous versions of Xamarin.Firebase.Messaging. Besides, this issue is so hard to reproduce in our dev and QA environments because it's so intermittent, it'd be nice if I could get some sort of feedback about why this could be happening and how best to deal with it.
Packages used:
<PackageReference Include="Xamarin.Forms" Version="4.8.0.1269" />
<PackageReference Include="Xamarin.Essentials" Version="1.5.3.2" />
<PackageReference Include="Xamarin.Firebase.Messaging" Version="71.1740.0" />
71.* nugets depend on old/legacy Android.Support, while 1xy.z.z.z depend on AndroidX. Xamarin.Forms with monodroid10.0 TFM depend on AndroidX, while monodroid9.0 depends on Android.Support.
Generally mixing is supposed to work, but usually can be cause of strong headaches. Try updating everything to latest versions I would suggest.
Thanks for the reply.
I'm going to update my packages, because it really can't hurt to do that, but I'm not hopeful that that's going to end up being my issue.
My main concern is whether or not it's normal to need to check a device's token when the application is starting using the GetToken() method. I haven't seen anyone really discuss a need to use GetToken() instead of OnNewToken(), but I have to assume that there could be times that the call to OnNewToken() may fail (e.g. battery saving / power settings, the way certain apps settle in the background, etc). It seems like it couldn't hurt to have some redundancy to ensure your device and code have the token everyone expects, but no one seems to discuss a need to do this.
Does it fall under "best practices" to check a device token like this, or am I missing something?
GetToken is deprecated. Use OnNewToken to receive a new token if one is created. Save it locally in addition to using it for your ANH registration as it only fires when a new token is created.