Android:第一次运行时,Firebase标记为空

我正在使用FCM在我的应用程序中提供通知。 一切运行良好,但现在我意识到,当我使用Android Studio(而不是从GooglePlay)安装我的应用程序时,标记在第一次运行时为空。 当我closures我的应用程序并重新启动它时,令牌不再为空。 是什么原因导致这个问题,我该如何避免呢?

InstanceIDService:

public class InstanceIDService extends FirebaseInstanceIdService { @Override public void onTokenRefresh() { String token = FirebaseInstanceId.getInstance().getToken(); registerToken(token); } private void registerToken(String token) { OkHttpClient client = new OkHttpClient(); RequestBody body = new FormBody.Builder() .add("Token",token) .build(); Request request = new Request.Builder() .url("url_to_registration_script") .post(body) .build(); try { client.newCall(request).execute(); } catch (IOException e) { e.printStackTrace(); } } } 

在MainActivity中:

 FirebaseMessaging.getInstance().subscribeToTopic("topic"); String token = FirebaseInstanceId.getInstance().getToken(); Log.d("TOKEN", token); 

应用程序安装并首次启动时,上次的日志返回null

注册脚本:

  <?php if (isset($_POST["Token"])) { $_uv_Token=$_POST["Token"]; $conn = mysqli_connect("localhost","user","pass","db") or die("Error connecting"); $q="INSERT INTO users (Token) VALUES ( '$_uv_Token') " ." ON DUPLICATE KEY UPDATE Token = '$_uv_Token';"; mysqli_query($conn,$q) or die(mysqli_error($conn)); mysqli_close($conn); } ?> 

Solutions Collecting From Web of "Android:第一次运行时,Firebase标记为空"

令牌在第一次应用程序启动时被asynchronous提取。 您必须等待onTokenRefresh()FirebaseInstanceIdService被调用才能访问该令牌。

从模拟器中卸载应用程序并再次运行,以便再次调用onTokenRefreshed方法。

要检查你是否已经注册,你只是想知道FCM托肯

 String refreshedToken = FirebaseInstanceId.getInstance().getToken(); 

在MyFirebaseMessagingService类的任何地方添加上面的行(在oncreate方法中),只是Toast或者loggingrefreshedToken。

即使我有同样的问题。 我给了Log语句来在我的启动器活动的onCreate中打印令牌。 卸载应用程序后,刷新令牌需要时间。 这就是为什么你得到空。 您必须等待一点才能刷新令牌。

我刚刚陷入同样的​​问题,这是我的方式。 在您的活动的onCreate()方法的某处调用该块。 我想把令牌发送给我的分析服务器,所以你必须根据你的需要来改变它。

这是我遵循的示例。

 private void subscribeUserToParse() { String deviceToken = FirebaseInstanceId.getInstance().getToken(); if (TextUtils.isEmpty(deviceToken)) { Intent intent = new Intent(this, MyFirebaseInstanceIDService.class); startService(intent); return; } User user = UserUtil.retrieveUserFromDB(mRealm); String objectId = user.getParseObjectId(); if (!TextUtils.isEmpty(objectId)) { ParseUtils.subscribeWithUsersObjectId(objectId, deviceToken); } } 

我面临同样的问题。 我浏览了大量SOpost和其他论坛,并find了适合我的解决scheme。 FCM文档说使用这种方法来获取令牌。

 String refreshedToken = FirebaseInstanceId.getInstance().getToken(); 

我在网上发现一篇文章(我道歉,我不记得是哪一个,我刚才发现)使用这个方法:

 String refreshedToken = FirebaseInstanceId.getInstance().getToken() (String authorizedEntity, String scope); 

FCM文档将第一种方法描述为:

返回默认Firebase项目的主令牌。

而第二个被描述为:

返回授权实体代表由实例ID标识的应用程序执行操作的令牌。 这与OAuth2令牌相似,除了适用于应用程序实例而不是用户。 例如,要获取可用于通过FirebaseMessaging向应用程序发送消息的令牌,请将其设置为发件人ID,并设置为“FCM”。

我一直在寻找为什么第一个方法调用需要更长的时间来返回一个令牌,但我还没有find答案呢。 希望这可以帮助。

只要更换:

 String token = instanceID.getToken(); 

有:

 String token = instanceID.getToken($SENDER_ID, "FCM"); 

它会工作。

在编写正确的代码后,我面临的最大问题是: – 不是构buildgradle中的最新版本的google play服务,因此,请始终使用firebase在设置对话框中显示的google-play-services版本