【问题标题】:Firebase FCM token - When to send to server?Firebase FCM 令牌 - 何时发送到服务器?
【发布时间】:2016-11-15 09:11:30
【问题描述】:

好的,所以我有一个应用程序,它在第一次启动时会带您浏览几张欢迎幻灯片,然后将您带到登录/注册页面,然后到 MainActivity

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

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

可能的解决方案

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

【问题讨论】:

标签: android mysql firebase firebase-cloud-messaging


【解决方案1】:

是的 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);
}

【讨论】:

  • 所以我可以做同样的事情,但也可以在第一次启动时在我的 MainActivity 中将令牌发送到服务器,因为使用该应用程序的唯一方法是注册,并且服务第一次启动时没有用户 ID,所以它不会发送到服务器。我想这就是我的解决方案。不是第一次拿到token的时候就发给服务器吗?或者你只是稍后再做,但没有包含代码?
【解决方案2】:

我们是这样处理的:

  1. 我们的服务器根据用户 ID(主键)创建/更新令牌值
  2. 使用 2 个 SharedPreferences
    1. 字符串 - 令牌字符串
    2. 布尔值(更新)- 令牌是否在服务器上更新。

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

【讨论】:

  • 有没有办法只使用用户的电子邮件(都在服务器端)来获取令牌?
  • @Andrea firebase 不会知道用户的电子邮件,对吧?那么你将如何查询呢?
  • Firebase 用户持有用户的一些值,其中之一是电子邮件https://firebase.google.com/docs/auth/admin/manage-users
【解决方案3】:

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

FirebaseInstanceID.getInstance().getToken();

如果令牌尚未生成,则返回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();

          }
      });

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

【讨论】:

    【解决方案4】:

    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();
    
              }
          });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 2019-11-13
      • 1970-01-01
      • 2016-05-23
      • 2020-08-03
      • 1970-01-01
      相关资源
      最近更新 更多