FCMを使用するのは初めてです。
firebase/quickstart-Android からサンプルをダウンロードし、FCMクイックスタートをインストールしますが、ログからトークンを取得できませんLOG TOKENボタンを押してもアプリで。
次に、Firebaseコンソールでメッセージを送信し、アプリパッケージ名をターゲットに設定しようとしました。受信メッセージがありました。
FCMを使用できますか?.
溶液:
私はAndroid開発者ではなく、単なるバックエンド開発者ではないため、解決するには時間がかかります。私の意見では、サンプルアプリにバグがあります。
コード:
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でトークンを取得できますが、最後に便利な方法を取得して取得します。デバッグモードを使用してサンプルアプリをインストールするだけで、初めてインストールするときにトークンを取得できます。
ただし、dont why it can
tをインストールするとログが出力されます。モバイルシステムに関連している可能性があります。
そして、なぜ私は通知を取得することができません。 FirebaseMessagingService.onMessageReceivedは呼び出しませんでしたsendNotification
手っ取り早い解決策は、それを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 :("));
より良い選択肢は、サービスを作成し、同様のロジック内に留めることです。最初に新しいサービスを作成する
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());
バージョン17.x.xより古いFirebaseライブラリを使用している場合でもまだ動作します。
重要な情報です。
google Playサービスがハングしたか実行されていない場合は、fcm return token =
null
Playサービスが正しく機能している場合、FirebaseInstanceId.getInstance().getToken()
メソッドはtoken
を返します。
Log.d("FCMToken", "token "+ FirebaseInstanceId.getInstance().getToken());
Docによると
onTokenRefresh()
instanceIDトークンが更新された場合にのみ呼び出されます
だからあなたがあなたのデバイスにアプリをインストールしたときに初めて呼び出されます。
だから私はあなたのアプリを手動でアンインストールしてもう一度実行してみてください
間違いなくあなたはTOKENを得ます
Firebase Android SDKの背後にあるチームはAPIを少し変更します。私はこのように "サーバーへのトークン"ロジックを実装しました:
FirebaseMessagingServiceの私のインスタンスでは:
public class FirebaseCloudMessagingService extends FirebaseMessagingService {
...
@Override
public void onNewToken(String token) {
// sending token to server here
}
...
}
トークンはデバイスごとであり、ログインロジックに関係なくFirebaseによって更新される可能性があることに注意してください。そのため、ログインおよびログアウト機能がある場合は、追加のケースを考慮する必要があります。
新しいAPIを使用すると、このようにトークンを取得できます。
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
@Override
public void onSuccess(InstanceIdResult instanceIdResult) {
String token = instanceIdResult.getToken();
// send it to server
}
});
頑張ってください
これを試して。なぜRegistrationIntentService
を使っているのですか?
public class FirebaseInstanceIDService extends FirebaseInstanceIdService {
@Override
public void onTokenRefresh() {
String token = FirebaseInstanceId.getInstance().getToken();
registerToken(token);
}
private void registerToken(String token) {
}
}
この行はあなたにfirebaseのFCMトークンを取得するはずです。
String token = FirebaseInstanceId.getInstance().getToken();
Log.d("MYTAG", "This is your Firebase token" + token);
Log.dを実行してAndroidモニターに印刷します。
これの代わりに:
// [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を受け取るためにこれをマニフェストファイルに含めることを忘れないでください。
<service
Android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action Android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
firebase-messaging:17.1.0
以降ではFirebaseInstanceIdServiceは推奨されません。 https://stackoverflow.com/a/51475096/で説明されているように、onNewToken
クラスのFirebaseMessagingService
を取得できます。 1351469
しかし、いつでもトークンを取得したい場合は、次のようにします。
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( this.getActivity(), new OnSuccessListener<InstanceIdResult>() {
@Override
public void onSuccess(InstanceIdResult instanceIdResult) {
String newToken = instanceIdResult.getToken();
Log.e("newToken",newToken);
}
});
Firebaseの認証機能を使用している場合は、これを使用してトークンを取得できます。
//------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()
これを試して
FirebaseInstanceId.getInstance().instanceId.addOnSuccessListener(OnSuccessListener<InstanceIdResult> { instanceIdResult ->
fcm_token = instanceIdResult.token}
ここに着陸した人たちのために、今までのところ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>
トークンを取得するには、Firebase(FCM)で次のものを使用します。
FirebaseInstanceId.getInstance().getToken();
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()));