Как мне обработать ситуацию, когда пользователь моего приложения и я не хочу, чтобы он получать уведомления на устройство.
Я попытался
FirebaseInstanceId.getInstance().deleteToken(FirebaseInstanceId.getInstance().getId(), FirebaseMessaging.INSTANCE_ID_SCOPE)
Но я до сих пор получаю уведомления на моем устройстве'ид_регистрации-ный`.
Я также убедился, что это знак, который я должен удалить:
FirebaseInstanceId.getInstance().getToken(FirebaseInstanceId.getInstance().getId(), FirebaseMessaging.INSTANCE_ID_SCOPE)
или просто FirebaseInstanceId.деыпзьапсе().getToken()`).
Я также попробовал FirebaseInstanceId.деыпзьапсе().deleteInstanceId (), но тогда в следующий раз, когда я называю FirebaseInstanceId.деыпзьапсе.getToken
я получаю значение null (он работает со второй попытки).
Я думаю, после deleteInstanceId я могу сразу позвонить getToken () снова, но это похоже на хак. И там'ы этот ответ в котором говорится, что он должен'т быть сделано, но он предлагает исключить знак, который, видимо, не't работа.
Так что это правильный способ справиться с этим?
Ладно. Так мне удалось сделать некоторые испытания и пришли к следующим выводам:
deleteToken()
является аналогом getToken(строка, строка)
, но не getToken()
.Он работает только если идентификатор отправителя вы передаете это другим идентификатором отправителя (не тот ID, который можно увидеть в Google-сервисов.в JSON). Например, вы хотите разрешить другому серверу, чтобы отправить в вашем приложении, вы называете getToken (назальный THEIR_SENDER_ID;, то "ТСМ", У)`, чтобы дать им доверенность чтобы отправить в вашем приложении. Это позволит вернуть другой регистрационный знак, соответствующий только для данного конкретного отправителя.
В будущем, если вы решили удалить их доверенность чтобы отправить в вашем приложении, вы'будете потом пользоваться deleteToken (на"THEIR_SENDER_ID-то", то "ТСМ", у). Это приведет к аннулированию соответствующего маркера, и, когда отправитель пытается послать сообщение, как обычное поведение, они будут получать
NotRegistered` ошибка.
Особого упоминания заслуживает этого ответ на @князь, а конкретно пример кода помог мне с этим.
Как @уже MichałK делаешь в своем посте, после вызова deleteInstanceId()
, getToken () должен быть вызван для того чтобы отправить запрос на новый маркер. Однако, вы не'т иметь, чтобы называть ее второй раз. Так долго, как <осущест-вляется>
onTokenRefresh()</с>
onNewToken (), он должен автоматически инициировать предоставление вам нового ключа.
Для краткости, deleteInstanceId () в
> getToken () в
> Регистрация <ы>onTokenRefresh()
</с> onNewToken()
.
Примечание: звоню deleteInstanceId()` не только удалить маркер для собственного приложения. Он будет удалить все подписки на темы и всех остальных, связанных с экземпляром приложения.
Вы уверены, что вы'вновь зовет deleteToken () правильно? Ценность для аудитории должно быть (тоже видно из моего ответа, что вы связаны) есть "набор с сервером приложений,'идентификатор отправителя и quot сек;. Вы'повторного прохождения `getId (), который не совпадает с идентификатором отправителя (он содержит значение идентификатора экземпляра приложения). Также, как вы отправляете сообщение (консоль сервера приложений или уведомлений)?
getToken()
и getToken(строка, строка)
возвращает разные маркеры. Смотрите мой ответ здесь.
я также попробовал
FirebaseInstanceId.деыпзьапсе().deleteInstanceId (), но тогда в следующий раз, когда я называю FirebaseInstanceId.деыпзьапсе.getToken
я получаю значение null (он работает со второй попытки).
Это's наверное потому что первый раз вы'вновь зовет getToken()
, он's по-прежнему создается. Это's просто обычное поведение.
я думаю, после deleteInstanceId я могу сразу позвонить getToken () снова, но это похоже на хак.
Не правда. Это's, как вы'll получить новый автоматически (при условии, что он уже сформирован) маркер. Поэтому я думаю, что это's прекрасно.
Я работал над той же проблемой, когда я сделал логаут моя ()
из моего приложения. Но проблема была в том, что после выхода, я был по-прежнему получать push-уведомления от опорного пункта. Я пытался удалить маркер опорного пункта. Но после удаления маркера в мой "выход". (метод), это
нуль, когда я запрашиваю его в мой логин()
метод. Проработав 2 дня я, наконец, получил решение.
новый AsyncTask<пустота,пустота,пустота и GT;() { @Переопределить охраняемых недействительными doInBackground(пустота... параметры) { попробовать { FirebaseInstanceId.деыпзьапсе().deleteInstanceId(); } поймать (исключение IOException е) { е.печатные(); } возвращать значение null; }
@Переопределить охраняемых недействительными onPostExecute реализовывались(результат недействительными) { // Вызов вашей деятельности, где вы хотите получить землю после выхода } }.выполнить();
новый AsyncTask<пустота,пустота,пустота и GT;() { @Переопределить охраняемых недействительными doInBackground(пустота... параметры) { Строку маркера = FirebaseInstanceId.деыпзьапсе().getToken(); // Используется для получения опорного пункта знак, пока его значение null, поэтому это избавит вас от нулевой указатель исключения пока(знак == значение null) { знак = FirebaseInstanceId.деыпзьапсе().getToken(); } возвращать значение null; } @Переопределить охраняемых недействительными onPostExecute реализовывались(результат недействительными) { } }.выполнить();
Я сделал небольшое исследование о том, что будет наиболее элегантное решение, чтобы получить обратно полный контроль (подписаться и отписаться ТСМ), как и раньше. Включение и отключение ТСМ после входа пользователя в систему или выход.
Шаг 1. - Автоматическая инициализация
Военнослужащих теперь обрабатывать Ид
и все остальное, что необходимо создать регистрационный знак. В первую очередь необходимо предотвратить автоматическая инициализация. На основании официальный набор документацию Вам необходимо добавить их мета-данных значения в AndroidManifest.xml`:
<?xml version="1.0" encoding="utf-8"?>
<application>
<!-- FCM: Disable auto-init -->
<meta-data android:name="firebase_messaging_auto_init_enabled"
android:value="false" />
<meta-data android:name="firebase_analytics_collection_enabled"
android:value="false" />
<!-- FCM: Receive token and messages -->
<service android:name=".FCMService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
</application>
Теперь вы отключили автоматический процесс запроса маркера. В то же время у вас есть возможность вновь включить ее во время выполнения кода.
Шаг 2. - Реализации enableFCM()и
disableFCM()` функции
Если вы снова включите автоматический инициализации то вы сразу получили новый знак, так что это идеальный способ, чтобы реализовать enableFCM()
метод.
Все подписки присваивается идентификатор экземпляра, поэтому, когда вы удалите его затем инициировать отписаться всех тему. На этом пути вы сможете реализовать disableFCM()
метод, просто сворачиваете авто-инициализации, прежде чем вы удалите его.
public class FCMHandler {
public void enableFCM(){
// Enable FCM via enable Auto-init service which generate new token and receive in FCMService
FirebaseMessaging.getInstance().setAutoInitEnabled(true);
}
public void disableFCM(){
// Disable auto init
FirebaseMessaging.getInstance().setAutoInitEnabled(false);
new Thread(() -> {
try {
// Remove InstanceID initiate to unsubscribe all topic
// TODO: May be a better way to use FirebaseMessaging.getInstance().unsubscribeFromTopic()
FirebaseInstanceId.getInstance().deleteInstanceId();
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
}
Шаг 3. - FCMService
реализация - маркер и приема сообщений
На последнем шаге вам необходимо получить новый токен и отправить прямо на ваш сервер. Другой стороны, вы'll получает ваше сообщение данных и просто делать то, что вы хотите.
public class FCMService extends FirebaseMessagingService {
@Override
public void onNewToken(String token) {
super.onNewToken(token);
// TODO: send your new token to the server
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
String from = remoteMessage.getFrom();
Map data = remoteMessage.getData();
if (data != null) {
// TODO: handle your message and data
sendMessageNotification(message, messageId);
}
}
private void sendMessageNotification(String msg, long messageId) {
// TODO: show notification using NotificationCompat
}
}
Я думаю, что этот раствор является прозрачным, простым и прозрачным. Я испытан в производственных условиях и это's работает. Я надеюсь, это было полезно.
разработчики никогда не должны отменить регистрацию приложения клиента в качестве механизма для выход из системы или для переключения между пользователями, по следующим причинам:
регистрационный знак не'т, связанные с определенным пользователя. Если приложение клиент отменяет регистрацию, а затем перерегистрируются, приложение может получать тот же регистрационный знак или другой регистрационный знак.
отмена регистрации и перерегистрации может занять до пяти минут для распространения. В течение этого времени сообщения могут быть отклонены из-за незарегистрированные государства, и сообщения могут пойти в неправильном пользователей. Сделать будьте уверены, что сообщения идут к намеченной пользователей:
приложение-сервер может поддерживать сопоставление текущего пользователя и регистрационный знак.
клиентское приложение может затем проверить, чтобы убедиться, что сообщения, которые он получает матч вошедшего в систему пользователя.
эта цитата из устаревшей документации Google
Но есть основания считать это правдой - даже если вышеуказанная документация устарела.
Вы можете наблюдать это здесь - проверить, как они делают это в codelab https://github.com/firebase/functions-samples/blob/master/fcm-notifications/functions/index.js
и здесь https://github.com/firebase/friendlychat-web/blob/master/cloud-functions/public/scripts/main.js
С getToken () - это устаревший, использовать getInstanceId()` вместо того, чтобы регенерировать новый маркер. Он имеет такое же влияние.
public static void resetInstanceId() {
new Thread(new Runnable() {
@Override
public void run() {
try {
FirebaseInstanceId.getInstance().deleteInstanceId();
FirebaseInstanceId.getInstance().getInstanceId();
Helper.log(TAG, "InstanceId removed and regenerated.");
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
Я знаю, что я опаздываю на вечеринку. `deleteInstanceId () должен быть вызван из фонового потока, так как он'ы блокирующий вызов. Просто проверить метод deleteInstanceId () в [FirebaseInstanceId()](https://firebase.google.com/docs/reference/android/com/google/firebase/iid/FirebaseInstanceId.html#deleteInstanceId()) класс.
@WorkerThread
public void deleteInstanceId() throws IOException {
if (Looper.getMainLooper() == Looper.myLooper()) {
throw new IOException("MAIN_THREAD");
} else {
String var1 = zzh();
this.zza(this.zzal.deleteInstanceId(var1));
this.zzl();
}
}
Вы можете начать IntentService, чтобы удалить идентификатор экземпляра и связанные с ней данные.
Просто вызовите метод deleteToken в фоновом потоке при выходе:
FirebaseInstanceId.getInstance().deleteToken(getString(R.string.gcm_defaultSenderId), "FCM")
Первый аргумент принимает SenderID, как это определено в FireBaseConsole
Это занимает несколько секунд для обновления - и после этого, вы больше не будете получать уведомления ТСМ.