Firebase FCM 令牌 - 何时发送到服务器?

Firebase FCM token - When to send to server?

好的,我有一个应用程序,它首先会带您浏览几张欢迎幻灯片,然后带您进入 login/register 页面,然后进入 MainActivity

我刚刚实现了 FCM,服务在用户看到这些页面中的任何一个之前 token 生成了一个 token 。我怎样才能让服务 运行s after 我到达 MainActivity?

问题是我试图在刷新到 MySQL DB 后立即将令牌发送到相应的用户帐户,但由于用户尚未登录,因此 null 并且我向服务器发送的消息失败。设计这个的好方法是什么?我考虑过将令牌保存在 SharedPreferences 中并在用户登录后将其发送到服务器,但是当稍后刷新令牌时会造成很多复杂情况?!

可能的解决方案

我不确定我是否完全理解这 2 个服务如何 运行 但是在 onTokenRefresh 中说我只是将令牌保存到 SharedPreferences 并且在 MainActivity 中我从 SP 然后我将它发送到服务器。在这种情况下,当令牌被刷新时,新值将立即再次进入 SharedPreferences。但我仍然需要检查它是否是 SP 中的新值,然后将其重新上传到服务器。这令人困惑!

是的,FCM 令牌是自动生成的。但是试着换个角度看这个。

我就是这样处理的。

让 FCM 在您的应用启动后立即生成令牌。将调用 OnTokenRefresh,您只需将其保存在您的首选项中:

@Override
public void onTokenRefresh() {
    // Get updated InstanceID token.
    String refreshedToken = FirebaseInstanceId.getInstance().getToken();
    Log.d(TAG, "Refreshed token: " + refreshedToken);

    sendRegistrationToServer(refreshedToken);
}

private void sendRegistrationToServer(String token) {
    // Add custom implementation, as needed.
    SharedPreferenceUtils.getInstance(this).setValue(getString(R.string.firebase_cloud_messaging_token), token);
    
   // To implement: Only if user is registered, i.e. UserId is available in preference, update token on server.
   int userId = SharedPreferenceUtils.getInstance(this).getIntValue(getString(R.string.user_id), 0);
   if(userId != 0){
       // Implement code to update registration token to server
   }
}

希望你能认清道路。询问您是否需要更多许可。

编辑

使用新的 Firebase SDK (21.0.0),您需要覆盖 onNewToken() 方法而不是 onTokenRefresh()

 @Override
public void onNewToken(@NonNull String s) {
    super.onNewToken(s);
    sendRegistrationToServer(s);
}

我们是这样处理的:

  1. 我们的服务器create/update 用户标识(主键)的令牌值
  2. 使用 2 个 SharedPreferences
    1. 字符串 - 令牌字符串
    2. 布尔值(更新)- 令牌是否在服务器上更新。

在令牌刷新的情况下,我们更新令牌字符串并将布尔值设置为 false。 稍后,每当用户每次登录时,我们检查布尔值(更新),如果为假 - 我们将当前令牌附加到他的 ID 并将其发送到服务器并将更新设置为真。

请注意,您始终可以通过以下方式检索令牌:

FirebaseInstanceID.getInstance().getToken();

如果令牌尚未生成,这将 return null 或令牌已生成。在您的情况下,令牌很可能会在用户登录时生成。因此您应该能够在用户登录后立即将其发送到您的应用服务器。如果它不可用,那么您会像 Chintan Soni 提到的那样在 onTokenRefresh 回调中发送它。

编辑

使用新的 Firebase SDK (21.0.0),您将通过以下方式获得您的令牌:

 FirebaseInstallations.getInstance().getToken(false).addOnCompleteListener(new OnCompleteListener<InstallationTokenResult>() {
          @Override
          public void onComplete(@NonNull Task<InstallationTokenResult> task) {
              if(!task.isSuccessful()){
                  return;
              }
              // Get new Instance ID token
              String token = task.getResult().getToken();

          }
      });

您最好添加一个侦听器,以便对响应进行更多处理。

2020 年 12 月更新: 使用新的 Firebase SDK (21.0.0),您可以通过覆盖 onNewToken() 方法来获取它:

@Override
public void onNewToken(@NonNull String s) {
    super.onNewToken(s);
    sendRegistrationToServer(s);
}

或在您的范围内 FirebaseInstallations.getInstance() :

FirebaseInstallations.getInstance().getToken(false).addOnCompleteListener(new OnCompleteListener<InstallationTokenResult>() {
          @Override
          public void onComplete(@NonNull Task<InstallationTokenResult> task) {
              if(!task.isSuccessful()){
                  return;
              }
              // Get new Instance ID token
              String token = task.getResult().getToken();

          }
      });