Как запустить службу идентификации FCM только после запуска определенного действия?

Предположим, у меня есть LoginActivity, где пользователь может либо зарегистрироваться, либо войти в систему с существующими учетными данными. Я не хочу, чтобы FirebaseInstanceIdService генерировал токен, если пользователь не вошел в систему, и MainActivity приложения не запущено.

Спасибо

Ответ 1

Вы не можете заблокировать FirebaseInstanceIdService.onTokenRefresh() от вызова до тех пор, пока пользователь не войдет в систему.

Что вы можете сделать в своем случае:

  • В FirebaseInstanceIdService.onTokenRefresh() игнорировать событие, если пользователь не вошел в систему
  • Когда пользователь выполнит вход в систему FirebaseInstanceId.getToken() и != null вызовет onTokenRefresh() (или непосредственно вашу логику) вручную.

Таким образом вы можете обработать токен, когда пользователь выполнил вход в систему, и если токен недоступен (или повернут), вы позже получите событие onTokenRefresh().

Обновление (3 июля 2017 г.). В комментариях читатель напомнил, что FirebaseInstanceIdService.onTokenRefresh() можно вызвать после входа пользователя в систему.

Это правильно. Когда пользователь входит в систему, getToken() все равно может вернуться null, если onTokenRefresh() не был вызван ранее.

Вам нужно использовать этот случай в своем приложении. Скорее всего, пользователь может использовать приложение в любом случае, но вы не можете отправить push-уведомление, пока не получите токен.

Когда onTokenRefresh() наконец-то вызывается, если пользователь регистрируется раньше, чем вы можете связать токен с пользователем.

Ответ 2

Извините, но это невозможно. FirebaseInstanceIdService автоматически запускается при запуске приложения и генерирует Token. Имейте в виду, что это связано с приложением Instance. Не с одним конкретным пользователем. Если вы пытаетесь сохранить Token с одним конкретным пользователем (т.е. Когда пользователь выполнил вход в систему, вы сохраните его Token на сервере db для push-уведомления этого пользователя). Если вы делаете это, вы столкнетесь в будущем заключается в том, что если два пользователя используют одно приложение Instance, то push-уведомление может быть перенаправлено неверному пользователю. Надеюсь, вы поняли мою мысль.

Ответ 3

Я поддерживаю один флаг в shared pref, который указывает, отправлен ли gcm-маркер на сервер или нет. В окне Splash каждый раз, когда я вызываю один метод sendDevicetokenToServer. Этот метод проверяет, не является ли идентификатор пользователя пустым и gcm отправить статус, а затем отправить токен на сервер.

   public static void  sendRegistrationToServer(final Context context) {

    if(Common.getBooleanPerf(context,Constants.isTokenSentToServer,false) ||
            Common.getStringPref(context,Constants.userId,"").isEmpty()){

        return;
    }

    String token =  FirebaseInstanceId.getInstance().getToken();
    String userId = Common.getUserId(context);
    if(!userId.isEmpty()) {
        HashMap<String, Object> reqJson = new HashMap<>();
        reqJson.put("deviceToken", token);
        ApiInterface apiService =
                ApiClient.getClient().create(ApiInterface.class);

        Call<JsonElement> call = apiService.updateDeviceToken(reqJson,Common.getUserId(context),Common.getAccessToken(context));
        call.enqueue(new Callback<JsonElement>() {
            @Override
            public void onResponse(Call<JsonElement> call, Response<JsonElement> serverResponse) {

                try {
                    JsonElement jsonElement = serverResponse.body();
                    JSONObject response = new JSONObject(jsonElement.toString());
                    if(context == null ){
                        return;
                    }
                    if(response.getString(Constants.statusCode).equalsIgnoreCase(Constants.responseStatusSuccess)) {

                        Common.saveBooleanPref(context,Constants.isTokenSentToServer,true);
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call<JsonElement> call, Throwable throwable) {

                Log.d("", "RetroFit2.0 :getAppVersion: " + "eroorrrrrrrrrrrr");
                Log.e("eroooooooorr", throwable.toString());
            }
        });

    }

}

В классе MyFirebaseInstanceIDService

 @Override
public void onTokenRefresh() {
    // Get updated InstanceID token.
    String refreshedToken = FirebaseInstanceId.getInstance().getToken();
    Log.d(TAG, "Refreshed token: " + refreshedToken);

    // If you want to send messages to this application instance or
    // manage this apps subscriptions on the server side, send the
    // Instance ID token to your app server.
    Common.saveBooleanPref(this,Constants.isTokenSentToServer,false);
    Common.sendRegistrationToServer(this);

}