it-roy-ru.com

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

Я столкнулся с этой серьезной проблемой с моим Android-приложением при использовании Firebase. 1. Мое приложение получает токен при первом запуске 2. Я могу отправить уведомление с консоли Firebase на зарегистрированный токен 3. Если я снова попытаюсь отправить уведомление через консоль сразу после шага 2. Он показывает мне «незарегистрированный токен» после 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: Попытался подключиться к API HTTP FCM, используя тот же ключ и токен сервера, и получил следующий ответ:

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

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

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

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

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

16
Irfan Raza

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

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

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

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

0
Irfan Raza

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

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

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

и вы можете прочитать здесь также об ошибках 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;



        }
1
Digvijay Singh

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

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 и использовать его соответствующим образом.

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

0
Abdul Ahad