This answer has 2 solutions:
1) Using ANDROID_ID as a Device Identifier.
2) Using cloud functions and FCM to determine a bad token, after 1st message sent to it.
1)
Try Settings.Secure.ANDROID_ID to get the Device ID.
String deviceAppUID = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
if (deviceAppUID!=null) {
setFirebaseTokenInServer(deviceAppUID, FirebaseDeviceToken);}
Android is changing ANDROID_ID in 8.0 (API 26), so that it will apply only to the combination of specific app, user, and deviceId. When that happens, you aren't really getting a Device ID that is ALWAYS true for every app, but rather, you are getting a Device ID for your specific App, with its specific signing key, on your specific devise. You can uninstall the app, and reinstall the app, and the ANDROID_ID will be the same as it was before.
That makes it safer for the user, but would still allow you to persist the Firebase Device Tokens in case the registration token changes for these following reasons:
- App deletes Instance ID
- App is restored on a new device User
- uninstalls/reinstall the app
- User clears app data
Then in Firebase, you can save these as:
DeviceTokens:
deviceID: firebaseDeviceToken
deviceID: firebaseDeviceToken
2) Using Firebase Cloud Messaging and Firebase Google Cloud Functions to determine a bad token.
If you also use Cloud Functions to send the FCM to each listed deviceToken (as is necessary if multiple devices), you can check for a response after the first notification is sent. If there is an error, and the error returns a message stating the token is bad, you can handle the error and then delete it from the Server.
- No device ID is necessary, much safer for user.
- Sends 1 FCM to a bad token, but not again after that
- If Firebase Team changes its errors or error messages, you will have to change the function or this will no longer work.
See this answer for more details:
Handling refresh tokens for FCM device groups