如何仅在特定活动触发后启动FCM ID服务?
假设我有一个LoginActivity
用户可以注册或使用现有凭证登录。除非用户登录并且启动应用程序的MainActivity
,否则我不希望FirebaseInstanceIdService
生成令牌。如何仅在特定活动触发后启动FCM ID服务?
谢谢
不能被调用,直到用户登录阻止FirebaseInstanceIdService.onTokenRefresh()
,你可以在你的使用情况做的是:
- 在
FirebaseInstanceIdService.onTokenRefresh()
忽略如果事件用户未登录 - 当用户登录检查
FirebaseInstanceId.getToken()
并且如果!= null
调用onTokenRefresh()
(或直接您的逻辑)ma nually。
通过这种方式,您可以在用户登录时处理令牌,并且如果令牌不可用(或旋转),稍后您将收到onTokenRefresh()
事件。
更新(2017年7月3日):在评论读者提醒FirebaseInstanceIdService.onTokenRefresh()
可以在用户登录后可以称为
这是正确的。如果用户登录,getToken()
仍然可以返回null
如果onTokenRefresh()
以前未被调用过。
你需要在你的应用程序中处理这种情况。无论如何,用户最有可能使用该应用程序,但只有在收到令牌后才能发送推送通知。
当终于调用onTokenRefresh()
时,如果用户之前登录过,则可以将令牌与用户关联起来。
如果在用户登录后调用FirebaseInstanceIdService.onTokenRefresh()会发生异步调用,该怎么办? –
这可能会发生,您需要在应用中处理这种情况。无论如何,用户最有可能使用该应用程序,但只有在收到令牌后才能发送推送通知。然后,当您收到令牌时,您可以将其与以前登录的用户相关联。 (我也更新了答案) –
很好,但我认为我们需要在登录后删除实例并调用getInstance()方法,以防Firebase之前调用它从新生成的实例中获取新的令牌。 –
对不起,但这是不可能的。 FirebaseInstanceIdService
在应用程序启动时自动调用并生成Token
。请记住,它与应用程序Instance
有关。不与一个特定的用户。如果你正试图保存Token
与一个特定的用户(即当用户登录时,那么你将保存该服务器数据库token
推送通知该用户)。如果你这样做,你将面临的错误是,如果两个用户共享一个应用程序Instance
然后推送通知可能会被推送到错误的用户.. 希望你明白我的观点。
嗨Usmal。如何解决这个问题呢?也许从我的服务器上的注销用户中删除令牌关联,并将其添加到新登录的用户......您怎么看? – Alessandro
@Alessandro是的,我有一个问题..我做了你提到的 –
谢谢你,我做同样的事情! :) – Alessandro
我在共享pref中维护一个标志,它指示gcm令牌是否发送到服务器。在每次我调用一个方法sendDevicetokenToServer时,在Splash屏幕中。此方法检查用户标识是否为空,然后gcm发送状态,然后将令牌发送到服务器。
public static void sendRegistrationToServer(final Context context) {
if(Common.getBooleanPerf(context,Constants.isTokenSentToServer,false) ||
Common.getStringPref(context,Constants.userId,"").isEmpty()){
return;
}
String token = FirebaseInstanceId.getInstance().getToken();
String userId = Common.getUserId(context);
if(!userId.isEmpty()) {
HashMap<String, Object> reqJson = new HashMap<>();
reqJson.put("deviceToken", token);
ApiInterface apiService =
ApiClient.getClient().create(ApiInterface.class);
Call<JsonElement> call = apiService.updateDeviceToken(reqJson,Common.getUserId(context),Common.getAccessToken(context));
call.enqueue(new Callback<JsonElement>() {
@Override
public void onResponse(Call<JsonElement> call, Response<JsonElement> serverResponse) {
try {
JsonElement jsonElement = serverResponse.body();
JSONObject response = new JSONObject(jsonElement.toString());
if(context == null){
return;
}
if(response.getString(Constants.statusCode).equalsIgnoreCase(Constants.responseStatusSuccess)) {
Common.saveBooleanPref(context,Constants.isTokenSentToServer,true);
}
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void onFailure(Call<JsonElement> call, Throwable throwable) {
Log.d("", "RetroFit2.0 :getAppVersion: " + "eroorrrrrrrrrrrr");
Log.e("eroooooooorr", throwable.toString());
}
});
}
}
在MyFirebaseInstanceIDService类
@Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
Common.saveBooleanPref(this,Constants.isTokenSentToServer,false);
Common.sendRegistrationToServer(this);
}
只要打电话给'FirebaseInstanceId.getInstance()。为gettoken()'在'MainActivity'的'的onCreate()'。或者在活动中的任何地方,您认为您需要它。 –
根据日志,我的FirebaseInstanceIdService实现在应用程序启动时生成令牌。有什么办法可以防止这种情况发生? – Bravo
对不起。我有点困惑。你是指'FirebaseInstanceIdService.onTokenRefresh()'? –