无法获取 FCM 注册令牌

Posted

技术标签:

【中文标题】无法获取 FCM 注册令牌【英文标题】:Can't acquire FCM registration token 【发布时间】:2018-03-03 18:07:14 【问题描述】:

我正在尝试获取 FCM 注册令牌或设备令牌,以便从我的服务器向我的应用程序发送推送通知。

问题是我试图像下面显示的代码那样获取它,但即使在卸载并重新安装应用程序后也没有任何反应。我已经确定我的标签管理器正在工作,并且所有需要的服务都已经在 androidManifests.xml 中设置。

有关信息,我已经测试了来自 firebase 站点的推送通知,它工作得很好。但这不是我的目标。我不明白为什么我可以从 Firebase 发送通知,但在我的 Android Studio 控制台上看不到/获取 FCM 注册令牌。有什么我想念的吗。我是这种事情的初学者,已经被这个问题困扰了大约 1 周,我的智慧到此为止。希望有人能帮助我。提前感谢您的宝贵时间。

public class FirebaseIDService  extends FirebaseInstanceIdService 
    private static final String TAG = "MyFirebaseIdService";
    public String tok;

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

       //sendRegistrationToServer(refreshedToken);
   

   private void sendRegistrationToServer(String token) 
       // TODO: Implement this method to send token to your app server.
   

AndroidManifests.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.asii_developer.asiisupport">

    <uses-permission android:name="android.permission.INTERNET" />

    <!-- To auto-complete the email text field in the login form with the user's emails -->
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.READ_PROFILE" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />


    <application
        android:allowBackup="true"
        android:hardwareAccelerated="false"
        android:icon="@mipmap/planete"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:roundIcon="@mipmap/planete"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">


        <!--
        <service
            android:name=".DeviceToken">
            <intent-filter>

            </intent-filter>
        </service>
        -->

        <meta-data
            android:name="com.google.firebase.messaging.default_notification_color"
            android:resource="@color/colorPrimary" />
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <activity android:name=".PageBienvenueActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".PagedAccueilActivity" />
        <activity android:name=".FormActivity" />
        <activity android:name=".RecapActivity" />
        <activity android:name=".PageDeConnexion" />
        <activity android:name=".mot_de_passeActivity" />
        <activity
            android:name=".Liste_des_ticketsActivity"
            android:windowSoftInputMode="stateHidden|adjustPan" />
        <activity
            android:name=".ConversationActivity"
            android:windowSoftInputMode="stateHidden|adjustPan" />
        <activity android:name=".NotificationsActivity">
            <intent-filter>
                <action android:name="notifActivity" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>


        <service
            android:name=".MyFirebaseMessagingService"
            android:enabled="true"
            android:exported="false" >
            <intent-filter>

            <action android:name="com.google.Firebase.MESSAGING_EVENT"/>

            </intent-filter>
        </service>
        <service
            android:name=".FirebaseIDService"
            android:enabled="true"
            android:exported="false">
            <intent-filter>

            <action android:name="com.google.Firebase.INSTANCE_ID_EVENT"/>

        </intent-filter>
        </service>



    </application>

</manifest>

MyFireBaseMessagingService.xml

package com.example.asii_developer.asiisupport;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MyFirebaseMessagingService extends FirebaseMessagingService 

    private static final String TAG = "FCM Service";

    @Override

    public void onMessageReceived(RemoteMessage remoteMessage) 

        Log.d(TAG, "From: " + remoteMessage.getFrom());

        Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());

        Intent intent = new Intent(this, NotificationsActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 1,
                intent, PendingIntent.FLAG_ONE_SHOT);

        NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new
                NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.arrow)
                .setContentTitle("Message")
                .setContentText(remoteMessage.getNotification().getBody())
                .setAutoCancel(true)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager = (NotificationManager)
                getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(1, notificationBuilder.build());

    


【问题讨论】:

【参考方案1】:

试试这个:

    // [START refresh_token]
    @Override
    public void onTokenRefresh() 
        // Get updated InstanceID token.
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        Log.d(TAG, "Refreshed token: " + refreshedToken);
        Toast.makeText(this, "Refreshed token: " + refreshedToken, Toast.LENGTH_LONG).show();

        // Implement this method to send token to your app's server
       sendRegistrationToServer(refreshedToken);

    
// [END refresh_token]

还有一件事:

你需要调用 sendRegistrationToServer() 方法来更新 服务器上的令牌,如果您从服务器发送推送通知。

注意:

在以下情况下生成新的 Firebase 令牌(调用 onTokenRefresh()):

应用删除Instance ID 应用已在新设备上恢复 用户卸载/重新安装应用程序 用户清除应用数据。

希望这会有所帮助!祝你好运!

【讨论】:

我非常清楚何时生成令牌,这就是为什么我已经无数次尝试卸载并重新安装应用程序。我现在的主要目标是在发送之前在 Android Studio 控制台上打印令牌到服务器 重新安装应用程序后,再次尝试我的代码。您现在应该在手机上看到令牌。如果你不知道,请告诉我!另外,记录时令牌的价值是多少?是空的还是空的? 对不起,它不起作用..登录时它给我 null 您确定在清单中添加了&lt;service android:name=".MyFirebaseInstanceIDService"&gt; &lt;intent-filter&gt; &lt;action android:name="com.google.firebase.INSTANCE_ID_EVENT"/&gt; &lt;/intent-filter&gt; &lt;/service&gt;【参考方案2】:

您需要先致电FirebaseInstanceId.getToken()(可能在您的MainActivity 或任何相应的初始活动中。

onTokenRefresh() 仅在开始后触发当且仅当FirebaseInstanceId.getToken() 的初始调用返回 null。正如FCM docs中提到的:

每当生成新令牌时都会触发 onTokenRefreshcallback,因此在其上下文中调用 getToken 可确保您访问的是当前可用的注册令牌。如果尚未生成令牌,FirebaseInstanceID.getToken() 将返回 null。

【讨论】:

以上是关于无法获取 FCM 注册令牌的主要内容,如果未能解决你的问题,请参考以下文章

无法获取设备的推送令牌。检查您的 FCM 配置是不是有效

Firebase(FCM)如何获取令牌

FCM:无效的注册令牌。检查令牌格式

getExpoPushTokenAsync出现问题,错误“无法获取设备的GCM令牌”

Azure 通知中心 - “从令牌提供程序获取的令牌错误”

在Android中获取FCM消息令牌的正确方法是啥?