Firebase(FCM)如何获取令牌

时间:2016-06-13 10:29:14

标签: android firebase firebase-cloud-messaging

这是我第一次使用FCM。

我从firebase/quickstart-android下载了一个示例,然后安装了FCM Quickstart。但是我无法从日志中获取任何令牌,甚至点击应用中的 LOG TOKEN按钮

然后我尝试使用Firebase控制台发送消息并设置为定位到我的应用包名称。我收到了任何传入消息。

我想知道可以使用FCM吗?GCM一切正常。

解决方案:

因为我不是Android开发人员,只是一个后端开发人员。所以我需要一些时间来解决它。在我看来,示例应用程序中存在一些错误。

enter image description here

代码:

RegistrationIntentService.java

public class RegistrationIntentService extends IntentService {

    private static final String TAG = "RegIntentService";


    public RegistrationIntentService() {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        String token = FirebaseInstanceId.getInstance().getToken();
        Log.i(TAG, "FCM Registration Token: " + token);
    }
}

MyFirebaseInstanceIDService.java

public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {

    private static final String TAG = "MyFirebaseIIDService";

    /**
     * Called if InstanceID token is updated. This may occur if the security of
     * the previous token had been compromised. Note that this is called when the InstanceID token
     * is initially generated so this is where you would retrieve the token.
     */
    // [START refresh_token]
    @Override
    public void onTokenRefresh() {
        // Get updated InstanceID token.
//        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
//        Log.d(TAG, "Refreshed token: " + refreshedToken);
//
//        // TODO: Implement this method to send any registration to your app's servers.
//        sendRegistrationToServer(refreshedToken);
//
        Intent intent = new Intent(this, RegistrationIntentService.class);
        startService(intent);
    }
    // [END refresh_token]

    /**
     * Persist token to third-party servers.
     * <p>
     * Modify this method to associate the user's FCM InstanceID token with any server-side account
     * maintained by your application.
     *
     * @param token The new token.
     */
    private void sendRegistrationToServer(String token) {
        // Add custom implementation, as needed.
    }
}

在MainActivity.java中添加它。

 Intent intent = new Intent(this, RegistrationIntentService.class);
        startService(intent);

完成上述操作后,您可以在logcat中获取令牌。但最后我找到了方便的方法来获取它。只需使用调试模式安装示例应用,您可以在第一次安装时获取令牌。

但是我在安装时不会t why it can打印日志。可能与移动系统有关。

然后为什么我得不到通知。 FirebaseMessagingService.onMessageReceived 未调用 sendNotification

24 个答案:

答案 0 :(得分:75)

最快和最好的原型

快速解决方案是将其存储在sharedPrefs中,并将此逻辑添加到MainActivity或扩展Application的类中的onCreate方法。

FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(this, instanceIdResult -> {
    String newToken = instanceIdResult.getToken();
    Log.e("newToken", newToken);
    getActivity().getPreferences(Context.MODE_PRIVATE).edit().putString("fb", newToken).apply();
});

Log.d("newToken", getActivity().getPreferences(Context.MODE_PRIVATE).getString("fb", "empty :("));

CLEANER WAY

更好的选择是创建服务并保持类似的逻辑。首先创建新服务

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    @Override
    public void onNewToken(String s) {
        super.onNewToken(s);
        Log.e("newToken", s);
        getSharedPreferences("_", MODE_PRIVATE).edit().putString("fb", s).apply();
    }

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
    }

    public static String getToken(Context context) {
        return context.getSharedPreferences("_", MODE_PRIVATE).getString("fb", "empty");
    }
}

然后将其添加到AndroidManifest文件

<service
        android:name=".MyFirebaseMessagingService"
        android:stopWithTask="false">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
</service>

最后,您可以使用服务MyFirebaseMessagingService.getToken(Context);

中的静态方法

最快但是已弃用

Log.d("Firebase", "token "+ FirebaseInstanceId.getInstance().getToken());

当您使用旧的firebase库而不是版本17.x.x

时,它仍然有效

答案 1 :(得分:18)

重要信息。

  

如果谷歌播放服务挂起或未运行,   然后fcm返回令牌= null

如果播放服务正常,则FirebaseInstanceId.getInstance().getToken()方法会返回token

Log.d("FCMToken", "token "+ FirebaseInstanceId.getInstance().getToken());

答案 2 :(得分:13)

根据文件

Migrate a GCM client app to FCM

onTokenRefresh()
  

仅在InstanceID令牌更新时调用

因此,只有在您的设备上安装应用时才会调用。

所以我建议您手动卸载您的应用并尝试再次运行

绝对会得到 TOKEN

答案 3 :(得分:12)

Firebase Android SDK背后的团队稍微更改了API。我已经实现了这样的“令牌到服务器”逻辑:

在我的FirebaseMessagingService实例中:

public class FirebaseCloudMessagingService extends FirebaseMessagingService {

    ...

    @Override
    public void onNewToken(String token) {
        // sending token to server here
    }

    ...

}

请记住,令牌是针对每个设备的,并且无论您的登录逻辑如何,Firebase都可以更新令牌。因此,如果您具有登录和注销功能,则必须考虑其他情况:

  1. 新用户登录时,需要将令牌绑定到新用户(将其发送到服务器)。因为,令牌可能会在旧用户会话期间更新,并且服务器不知道新用户的令牌。
  2. 用户注销后,您需要取消绑定令牌。因为,用户不应再收到通知/消息。

使用新的API,您可以获得这样的令牌:

FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
        @Override
        public void onSuccess(InstanceIdResult instanceIdResult) {
            String token = instanceIdResult.getToken();
            // send it to server
        }
    });

祝你好运!

答案 4 :(得分:8)

试试这个。你为什么使用stdatomic.h

retain(object) {
    ++object.ref_count;  // pretty easy to make this atomic
} 

release(object) {
    if (--object.ref_count == 0)  // need this to be atomic also
        free(object)
}

答案 5 :(得分:8)

此行应该为您提供firebase FCM令牌。

String token = FirebaseInstanceId.getInstance().getToken();
Log.d("MYTAG", "This is your Firebase token" + token);

执行Log.d将其打印到Android监视器。

答案 6 :(得分:7)

而不是:

    // [START refresh_token]
    @Override
    public void onTokenRefresh() {
//        Get updated InstanceID token.
//        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
//        Log.d(TAG, "Refreshed token: " + refreshedToken);
//
//        TODO: Implement this method to send any registration to your app's servers.
//        sendRegistrationToServer(refreshedToken);
//
        Intent intent = new Intent(this, RegistrationIntentService.class);
        startService(intent);
    }
    // [END refresh_token]

这样做:

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

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

    }
    // [END refresh_token]

还有一件事:

  

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

<强>更新

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

  • 该应用删除实例ID
  • 该应用已在新设备上恢复
  • 用户卸载/重新安装应用
  • 用户清除应用数据。

答案 7 :(得分:5)

您可以使用此方法通过 firebase 获取设备令牌

 FirebaseMessaging.getInstance().getToken().addOnCompleteListener(new OnCompleteListener<String>() {
        @Override
        public void onComplete(@NonNull Task<String> task) {
            String deviceToken = task.getResult();
        }
    });

答案 8 :(得分:5)

同时不要忘记将此包含在您的清单文件中以接收令牌ID

return

答案 9 :(得分:4)

firebase-messaging:17.1.0及更高版本中,不推荐使用FirebaseInstanceIdService,您可以按照https://stackoverflow.com/a/51475096/1351469

的说明在onNewToken类上获取FirebaseMessagingService

但是,如果您想随时获取令牌,那么现在您可以这样做:

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

答案 10 :(得分:3)

如果正在使用firebase的某些auth功能,您可以使用此功能获取令牌:

//------GET USER TOKEN-------
FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
mUser.getToken(true)
        .addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
            public void onComplete(@NonNull Task<GetTokenResult> task) {
                if (task.isSuccessful()) {
                    String idToken = task.getResult().getToken();
                      // ...
                }
            }
        });

如果用户已登录,则工作正常。的 getCurrentUser()

答案 11 :(得分:3)

FirebaseInstanceId.getInstance().getInstanceId()deprecated。基于firebase document,您可以使用以下代码检索当前的注册令牌:

FirebaseMessaging.getInstance().getToken()
    .addOnCompleteListener(new OnCompleteListener<String>() {
        @Override
        public void onComplete(@NonNull Task<String> task) {
          if (!task.isSuccessful()) {
            Log.w(TAG, "Fetching FCM registration token failed", task.getException());
            return;
          }

          // Get new FCM registration token
          String token = task.getResult();

          // Log and toast
          String msg = getString(R.string.msg_token_fmt, token);
          Log.d(TAG, msg);
          Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
        }
    });

答案 12 :(得分:2)

这是在 Activity (2021) 中获取 fcm 令牌的最新代码。

FirebaseMessaging.getInstance().getToken()
                .addOnCompleteListener(new OnCompleteListener<String>() {
                    @Override
                    public void onComplete(@NonNull Task<String> task) {
                        if (!task.isSuccessful()) {
                            Log.w(TAG, "Fetching FCM registration token failed", task.getException());
                            return;
                        }
                        // Get new FCM registration token
                        String token = task.getResult();

                        Log.d(TAG, "fcm token : "+token);
                        
                    }
                });

对于新令牌,只需在 FirebaseMessagingService 扩展类中添加 newToken 方法即可。

@Override
    public void onNewToken(String token) {
        super.onNewToken(token);
        Log.d(TAG, token);
    }

答案 13 :(得分:1)

对于那些降落在这里的人,FirebaseInstanceIdService到现在为止已被弃用,请改用:

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    @Override
    public void onNewToken(String token) {
        Log.d("MY_TOKEN", "Refreshed token: " + token);

        // If you want to send messages to this application instance or
        // manage this apps subscriptions on the server side, send the
        // Instance ID token to your app server.
        // sendRegistrationToServer(token);
    }
}

并在AndroidManifest中声明

<application... >

<service android:name=".fcm.MyFirebaseMessagingService">
    <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>
</application>

答案 14 :(得分:1)

我会尽量简短。这是检索 Firebase 令牌的唯一非弃用方法:

FirebaseInstallations.getInstance().getToken(true).addOnCompleteListener(task -> { 
   // get token 
   String token = task.getResult().getToken();      
})

答案 15 :(得分:1)

尝试

FirebaseInstanceId.getInstance().instanceId.addOnSuccessListener(OnSuccessListener<InstanceIdResult> { instanceIdResult ->
             fcm_token = instanceIdResult.token}

答案 16 :(得分:1)

在挂起函数中获取 firebase 令牌的示例

override suspend fun sendTokenToServer() {
    try {
 
        val token = FirebaseMessaging.getInstance().token.await()
        Log.i("TAG", "token " + token)
    } catch (exception:Exception) {

    }
}

答案 17 :(得分:0)

使用以下代码获取最新的 Firebase 版本 - 'com.google.firebase:firebase-messaging:22.0.0'

FirebaseMessaging.getInstance().getToken()
                        .addOnCompleteListener(task -> {

                            if (!task.isSuccessful()) {
                                //handle token error
                                return;
                            }

                            strAppToken = task.getResult();

                        });

答案 18 :(得分:0)

更新11-12-2020

使用'com.google.firebase:firebase-messaging:21.0.0'时是FirebaseInstanceIdis depreacted now

现在我们需要使用FirebaseInstallations.getInstance().getToken()FirebaseMessaging.getInstance().token

示例代码

FirebaseInstallations.getInstance().getToken(true).addOnCompleteListener {
            firebaseToken = it.result!!.token
        }

// OR

FirebaseMessaging.getInstance().token.addOnCompleteListener {
            if(it.isComplete){
                firebaseToken = it.result.toString()
                Util.printLog(firebaseToken)
            }
        }

答案 19 :(得分:0)

FirebaseInstanceId.getInstance()。getInstanceId()已弃用。 现在获取用户FCM令牌

 FirebaseMessaging.getInstance().getToken()
            .addOnCompleteListener(new OnCompleteListener<String>() {
                @Override
                public void onComplete(@NonNull Task<String> task) {
                    if (!task.isSuccessful()) {
                        System.out.println("--------------------------");
                        System.out.println(" " + task.getException());
                        System.out.println("--------------------------");
                        return;
                    }

                    // Get new FCM registration token
                    String token = task.getResult();

                    // Log 
                    String msg = "GET TOKEN " + token;
                    System.out.println("--------------------------");
                    System.out.println(" " + msg);
                    System.out.println("--------------------------");

                }
            });

答案 20 :(得分: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();

            }
        });

答案 21 :(得分:0)

getToken()已过时。您可以改用getInstanceId()。

如果要在请求instanceId(token)时处理结果,请检查此代码。

    FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(instanceIdResult -> {
    if (instanceIdResult != null) {
        String token = instanceIdResult.getToken();
        if (!TextUtils.isEmpty(token)) {
            Log.d(TAG, "retrieve token successful : " + token);
        }
    } else{
        Log.w(TAG, "instanceIdResult should not be null..");
    }
}).addOnFailureListener(e -> {
    //do something with e
}).addOnCanceledListener(() -> {
    //request has canceled
}).addOnCompleteListener(task -> Log.v(TAG, "task result : " + task.getResult().getToken()));

答案 22 :(得分:0)

您可以在Firebase(FCM)中使用以下命令获取令牌:

FirebaseInstanceId.getInstance().getToken();

答案 23 :(得分:-8)

Settings.Secure.getString(getContentResolver(),
                     Settings.Secure.ANDROID_ID);