Незарегистрированная ошибка токена после отправки одного уведомления
Я столкнулся с этой драматической проблемой с моим приложением 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 не обновляется до тех пор, пока приложение не будет переустановлено.