如何在安卓设备上保存FCM令牌?

9

我正在按照这个链接中的步骤在Firebase上注册我的设备。

在此,我尝试显示并保存通知令牌。

    public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {

    private static final String TAG = "MyFirebaseIIDService";

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

    private void storeToken(String token) {
        //saving the token on shared preferences
        SharedPrefManager.getInstance(getApplicationContext()).saveDeviceToken(token);
    }
}

当我尝试注册时,它总是会显示“Token未生成”的错误信息,这个错误信息出现在MainActivity表单中。
所以,我的应用程序已连接到Firebase,并且我知道FirebaseInstanceIdService已被弃用。我也尝试过使用它。
public class MyFirebaseInstanceIDService extends FirebaseMessagingService {

    private static final String TAG = "MyFirebaseIIDService";

    @Override
    public void onNewToken(String refreshedToken) {
        refreshedToken = FirebaseInstanceId.getInstance().getInstanceId().getResult().getToken();
        Log.d(TAG, "Refreshed token: " + refreshedToken);
        storeToken(refreshedToken);
    }

    private void storeToken(String token) {
        //saving the token on shared preferences
        SharedPrefManager.getInstance(getApplicationContext()).saveDeviceToken(token);
    }
}

但仍未生成相同的令牌。


它在窗口日志中显示吗? - mducc
请阅读以下内容:https://dev59.com/iKbja4cB1Zd3GeqPn-wM 和 https://dev59.com/w1oU5IYBdhLWcg3wcmq8 - Shruti
5个回答

18
onTokenRefresh/onNewToken方法仅在生成新的标记时才会被调用。
通常情况下(特别是在开发过程中),您的应用程序在添加服务之前已经生成了实例ID令牌。因此, onTokenRefresh / onNewToken 将不会被调用,并且您的共享首选项中将没有令牌。
因此,您应该直接从主要活动使用 FirebaseInstanceId.getInstance().getInstanceId()获取令牌,如文档中所示。 这将获取最后生成的令牌。 从那时起,您可以使用 onTokenRefresh / onNewToken 来响应标记更改。

现在我明白了,Token只有在应用程序第一次安装时才会生成...获取Token后,我尝试添加Shared prefs,但是在卸载后它可以正常工作。 - Don't Be negative
那么,我每次运行时都可以获得令牌,而无需卸载吗?如果已经生成了令牌,我就不会调用生成令牌的服务。 - Don't Be negative
卸载确实会清除令牌。因此,在重新安装时,将调用您的 onTokenRefresh/onNewToken。正如我在答案中所说,如果您只想在主活动中获取令牌,请调用 FirebaseInstanceId.getInstance().getInstanceId()。如果没有生成令牌,则最终将调用您的 onTokenRefresh/onNewToken - Frank van Puffelen
谢谢,现在我明白了,有了你和@MLN的帮助。谢谢。 - Don't Be negative
@FrankvanPuffelen,你能帮我解决同样的问题吗?即使在第一次运行时,我的令牌也没有生成。这是我的问题链接:https://stackoverflow.com/questions/52658578/firebase-fcm-token-not-generating?noredirect=1#comment92247828_52658578 - Vivek Mishra

9
只需将此代码添加到您的代码中即可。
    public class MyActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);


        SharedPreferences prefs = getSharedPreferences("TOKEN_PREF", MODE_PRIVATE);
        String token = prefs.getString("token", "");

        Log.e("NEW_INACTIVITY_TOKEN", token);

        if (TextUtils.isEmpty(token)) {
            FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(MyActivity.this, new OnSuccessListener<InstanceIdResult>() {
                @Override
                public void onSuccess(InstanceIdResult instanceIdResult) {
                    String newToken = instanceIdResult.getToken();
                    Log.e("newToken", newToken);
                    SharedPreferences.Editor editor = getSharedPreferences("TOKEN_PREF", MODE_PRIVATE).edit();
                    if (token!=null){
                       editor.putString("token", newToken);
                       editor.apply();
                    }

                }
            });
        }

    }


}

Firebase Tokens 在应用程序安装并第一次运行时被调用,因此请忽略使用 Shared Prefs 保存数据或运行此 Activity/Service 的步骤。

是的,现在这个程序运行良好。每次打开应用也没有影响,而且令牌已成功保存。 - Don't Be negative

2
无需使用 getToken()新的令牌已经通过 onNewToken 参数返回
@Override
public void onNewToken(String refreshedToken) {
    // No need to assign refreshedToken with getToken,
    // this method called when token refreshed then use returned refreshedToken directly,
    // use `instanceIdResult.getToken()` described below when you need to use token later throw app usage.

    // refreshedToken = FirebaseInstanceId.getInstance().getInstanceId().getResult().getToken();
    Log.d(TAG, "Refreshed token: " + refreshedToken);
    storeToken(refreshedToken);
}

getToken(); 也已经被弃用

在您的 Activity 中获取 Token:如果您需要在活动中获取令牌,则使用以下方式,getToken(); 也已经被弃用:

FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( MyActivity.this,  new OnSuccessListener<InstanceIdResult>() {
     @Override
     public void onSuccess(InstanceIdResult instanceIdResult) {
           String newToken = instanceIdResult.getToken();
           Log.e("newToken",newToken);

     }
 });

1
你的答案已经过时了(Firebase似乎每隔几个月就会更改,即使你复制粘贴,他们的一半文档也无法正常工作,大量方法已被弃用或完全不同)。 - qkx

2

生成令牌可能需要一些时间。如果您没有收到它,可以按照以下步骤生成: (参考:https://firebase.google.com/docs/cloud-messaging/android/client?authuser=0)

 FirebaseInstanceId.getInstance().getInstanceId()
                    .addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() 
 {
                        @Override
                        public void onComplete(@NonNull Task<InstanceIdResult> task) 
   {
                            if (!task.isSuccessful()) {
                                Log.w(TAG, "getInstanceId failed", 
                                task.getException());
                                return;
                            }

                            // Get new Instance ID token
                            String token = task.getResult().getToken();
                            //Here you will surely get the token so store it in 
                            //sharedpreference for future use

                        }
 });

1

尝试卸载并重新安装应用程序,因为令牌不是每次玩应用程序时生成的。它是在您清除sharePref或重新安装时生成的。


是的,现在它运行得很好,令牌已生成,但是不卸载它不可能吗? - Don't Be negative

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接