问题
So, I need to refresh my token each time it expires, but the service runing behind ddoes not trigger onNewToken()
Manifest
<service
android:name=".fcm.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
Code
class MyFirebaseMessagingService: FirebaseMessagingService() {
override fun onNewToken(token: String) {
super.onNewToken(token)
val currentUser = FirebaseAuth.getInstance().currentUser?.uid
if(currentUser != null){
FirebaseFirestore.getInstance().collection("user").document(currentUser).update("deviceToken",token)
}
}
}
Does I need to explicitly call getInstanceID()
each time I go throught onStart() in my app ? or should this service update my deviceToken with the new one like I did ?
I have tested it with an old logged in account but notifications did not arrived, hence, the new token has not been refreshed (I needed to logout and login again to receive notifications once more)
回答1:
onNewToken. What documentation says:
Called when a new token for the default Firebase project is generated.
This is invoked after app install when a token is first generated, and again if the token changes.
What does it mean is that once the token has been generated this method will not be called until push token has to change.
When your app starts you must get instance of FirebaseInstanceId
and extract token form it. It will guarantee that you get a valid token.
You should leave the code in your onNewToken
method as it is and add the code mentioned below to handle cases when the token is already generated:
FirebaseInstanceId.getInstance().instanceId.addOnSuccessListener { instanceIdResult: InstanceIdResult ->
val currentUser = FirebaseAuth.getInstance().currentUser?.uid
if(currentUser != null){
FirebaseFirestore.getInstance().collection("user").document(currentUser).update("deviceToken", instanceIdResult.token)
}
}
Update: when to use it.
Firstly, you have to understand two things:
onNewToken
is called when a token is absent and has to be generated (after application installation) OR when the token has expired and has to be changed.FirebaseInstanceId.getInstance().instanceId.addOnSuccessListener(...)
is NOT generating any tokens! It only returns you currently available, valid, safe to use push notification token. There is no use to call it multiple times in your case.
So now you have onNewToken
in place and ready to process token changes. Good. Leave as is.
Now what you need to handle is a case when a token is already generated, valid and ready to use. onNewToken
will not be called in that case! Now it's your turn to manually request this token to be returned to you.
Example:
class YourActivity: Activity {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
uploadFcmToken()
}
private fun uploadFcmToken() {
FirebaseInstanceId.getInstance().instanceId.addOnSuccessListener { instanceIdResult: InstanceIdResult ->
val currentUser = FirebaseAuth.getInstance().currentUser?.uid
if(currentUser != null){
FirebaseFirestore.getInstance()
.collection("user")
.document(currentUser)
.update("deviceToken", instanceIdResult.token)
}
}
}
}
回答2:
Most likely you added the onNewToken
implementation after FCM had already generated the initial token.
For that specific case (which mostly affects you as the developer, but not your users) you'll want to also get the token in something like the onStart
of your main activity. Alternatively you can uninstall the app and reinstall it after adding onNewToken
for the first time, in which case it'll also generate a new token and call onNewToken
.
So you'll typically end up getting the token both in onNewToken
and in the onStart
of your app.
来源:https://stackoverflow.com/questions/63236185/firebase-onnewtoken-not-refreshing-my-token