Незарегистрированная ошибка токена после отправки одного уведомления

Я столкнулся с этой драматической проблемой с моим приложением android при использовании Firebase. 1. Мое приложение получает токен при первом запуске 2. Я могу отправить уведомление с консоли firebase на зарегистрированный токен 3. Если я попытаюсь отправить уведомление снова с консоли сразу после шага 2. Он показывает мне "незарегистрированный токен" после второй попытки.

У меня есть все необходимые настройки, которые уже есть в манифесте, и файл google service.json также имеет правильную конфигурацию. Я считаю, что все правильно, потому что приложение может получать уведомление один раз, и проблема начинается только после этого.

Обновление 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: Пытался поразить HTTP-api из FCM с помощью того же ключа и токена сервера и получил следующий ответ:

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

Просто, чтобы избежать перекрестных вопросов, несколько деталей:

  • Студия Android: v2.3.1
  • Версия сервисной программы Google: 10.0.1
  • Библиотеки включены: ядро, база данных, хранилище, обмен сообщениями - все имеют ту же версию, что и сервис google play 10.0.1

Обновление 3: авария Firebase, база данных и хранилище работают в одном проекте (который показывает, что файл google service.json верен).

Пожалуйста, помогите мне исправить это.

Ответы

Ответ 1

Вот как я исправил.

Как отмечалось всеми, имя пакета .json файла может быть основной причиной этого сбоя, который стал истинным и здесь, но с твистом.

Я загрузил файл .json из Firebase и предполагал, что был загружен правильный .json файл. К сожалению, из-за некоторой ошибки в Firebase при загрузке файла я всегда получал файл .json из моего другого проекта (firebase app). При инвестировании загруженного файла я понял это и изменил имя и ключи пакета вручную на .json файле.

Я предлагал всем проверить включенный файл .json, прежде чем пытаться что-либо еще, поскольку это является основной причиной этого типа проблем.

Ответ 2

Регистрационный токен может измениться, если:

  • Приложение удаляет идентификатор экземпляра
  • Приложение восстанавливается на новом устройстве
  • Пользователь удаляет/переустанавливает приложение
  • Пользователь удаляет данные приложения.

вы можете увидеть документацию здесь

и вы можете читать здесь также о ошибках fcm это происходит только для режима отладки, поэтому вы можете вызвать этот метод в своей активности запуска, это будет принимать сертификат HTTPS сервера Test/Development, поскольку сертификат 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;



        }

Ответ 3

Я помню, как раньше сталкивался с подобной проблемой. Вот что я сделал и работала гладко для меня. Надеюсь, это поможет,

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).
    }
}

Ответ 4

FCM - это противоположность GCM.

При использовании классов GCM TokenID обновляется время от времени, поэтому он также обновляется в базе данных на сервере.

При использовании FCM. Базовая архитектура FCM работает с уникальным TokenID, это причина, по которой onTokenRefresh не вызывает многократно. Он вызывает только один раз.

Что вам нужно сделать, просто сохраните свой INITIALLY сгенерированный токенID и используйте его соответствующим образом.

P.S: токен FCM не обновляется до тех пор, пока приложение не будет переустановлено.