web-dev-qa-db-ja.com

1つの通知を送信した後の未登録トークンエラー

Firebaseの使用中にAndroidアプリでこの劇的な問題に直面しています。1。アプリは最初の起動時にトークンを受信します2.Firebaseコンソールから登録済みのトークンに通知を送信できます3。手順2の直後にコンソールで再度通知を送信しようとすると、2回目以降に「未登録トークン」と表示されます。

マニフェストには必要なすべての構成が既にあり、googleservice.jsonファイルも正しい構成で配置されています。アプリは一度通知を受け取ることができ、その後問題が発生し始めるので、問題は正しいと思います。

アップデート1:アプリをアンインストールして再インストールすると、通知を1回しか受信できなくなります。

コードを見たい人は、これが私がトークンを取得する方法です:

@Override
public void onTokenRefresh() {

    //Getting registration token
     refreshedToken = FirebaseInstanceId.getInstance().getToken();

    //Displaying token on logcat
    Log.d(TAG, "Refreshed token: " + refreshedToken);
     saveDeviceToken(refreshedToken);
}

これは最初の起動でのみ呼び出しを受け取り、その後は呼び出されるのを見ていません(これは予想される動作だと思います)。

受信したOnMessageも最初の通知で呼び出され、その後呼び出されることはありません。

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    Log.d("FCM", "From: " + remoteMessage.getFrom());

    if (remoteMessage.getNotification() != null) {
        Log.d("FCM", "Notification Message Body: " + remoteMessage.getNotification().getBody());
        sendNotification(remoteMessage.getNotification().getBody());
    }
}

更新2:同じサーバーキーとトークンを使用してFCMのHTTP APIをヒットしようとしましたが、次の応答がありました。

   {
  "multicast_id": 6286279702096230688,
  "success": 0,
  "failure": 1,
  "canonical_ids": 0,
  "results": [
    {
      "error": "NotRegistered"
    }
  ]
}

クロス質問を避けるために、ここにいくつかの詳細があります。

  • Android Studio:v2.3.1
  • グーグルプレイサービスバージョン:10.0.1
  • 含まれているライブラリ:コア、データベース、ストレージ、メッセージング-すべてがグーグルプレイサービス10.0.1と同じバージョンを持っています

アップデート3:Firebaseがクラッシュし、データベースとストレージが同じプロジェクトで機能しています(これは、google service.jsonファイルが正しいことを示しています)。

それを修正するのを手伝ってください。

16
Irfan Raza

ここで私がどのように修正したか。

誰もが指摘しているように、.jsonファイルのパッケージ名がこの失敗の主な理由である可能性があります。これはここでも当てはまりますが、ひねりが加えられています。

Firebaseから.jsonファイルをダウンロードし、正しい.jsonファイルがダウンロードされていると想定していました。残念ながら、ファイルのダウンロードに関するFirebaseのバグが原因で、他のプロジェクト(firebaseアプリ)の.jsonファイルを常に取得していました。ダウンロードしたファイルを投資する際に、私はそれを理解し、.jsonファイルのパッケージ名とキーを手動で変更しました。

このタイプの問題の主な理由は、他のことを試す前に、含まれている.jsonファイルを確認することをすべての人に提案しました。

0
Irfan Raza

以前にも同じような問題に直面したことを覚えています。これが私がしたことであり、それは私にとってスムーズに機能します。お役に立てれば、

PreferenceStoreは、共有設定を保存、編集、および削除するためのヘルパークラスです。

@Override
public void onTokenRefresh() {
    String token = FirebaseInstanceId.getInstance().getToken();
    Log.i(TAG, "New FCM Token: " + token);

    setup_flag = PreferenceStore.getBoolean(getApplicationContext(), PrefKeys.IS_FIRST_FCM_TOKEN);
    if (!setup_flag) {
        // save token and boolean value in shared preferences for 
        // the first time you run the app after install
        PreferenceStore.saveString(getApplicationContext(), "FCM_TOKEN", token);
        PreferenceStore.saveBoolean(getApplicationContext(), "IS_FIRST_FCM_TOKEN", true);
    } else {
        // other time your app loads, update the token (like call the API endpoint).
    }
}
1
denizen

FCMはGCMの反対です。

GCMクラスを使用している間、TokenIDは時々更新されるため、サーバー上のデータベースでも更新されます。

FCMの使用中。 FCMの基本アーキテクチャは一意のTokenIDで機能します。これが、onTokenRefreshが複数回呼び出されない理由です。一度だけ呼び出します。

あなたがしなければならないのは、[〜#〜]最初に[〜#〜]生成されたTokenIDを保存し、それに応じてそれを利用することです。

追記:FCMトークンでは、アプリが再インストールされるまで更新されません。

0
Abdul Ahad

登録トークンは、次の場合に変更される可能性があります。

  • アプリはインスタンスIDを削除します
  • アプリは新しいデバイスに復元されます
  • ユーザーがアプリをアンインストール/再インストールします
  • ユーザーはアプリデータをクリアします。

あなたはドキュメントを見ることができます ここ

そして、あなたは読むことができます ここ これはデバッグモードでのみ発生するfcmエラーについても読むことができますので、ランチャーアクティビティでこのメソッドを呼び出すことができますこれはHTTPS証明書が無効であるため、テスト/開発サーバーのHTTPS証明書を受け入れます/信頼されていないリリースでは問題ありません。

private void RegisterFireBase()
        {

if (BuildConfig.DEBUG) {    
            Task.Run(() =>
            {
                var instanceId = FirebaseInstanceId.Instance;
                instanceId.DeleteInstanceId();
                Android.Util.Log.Debug("TAG", "{0} {1}", instanceId?.Token?.ToString(), instanceId.GetToken(GetString(Resource.String.gcm_defaultSenderId), Firebase.Messaging.FirebaseMessaging.InstanceIdScope));

            });


            ServicePointManager.ServerCertificateValidationCallback += (o, certificate, chain, errors) => true;



        }
0
Digvijay Singh