web-dev-qa-db-ja.com

特定のアクティビティがトリガーされた後にのみFCMIDサービスを起動するにはどうすればよいですか?

ユーザーが既存の資格情報で登録またはログインできるLoginActivityがあるとします。ユーザーがログインしてアプリケーションのFirebaseInstanceIdServiceが起動されない限り、MainActivityにトークンを生成させたくありません。

ありがとうございました

11
Bravo

ユーザーがログインするまで、FirebaseInstanceIdService.onTokenRefresh()の呼び出しをブロックすることはできません。

ユースケースでできることは次のとおりです。

  • FirebaseInstanceIdService.onTokenRefresh()で、ユーザーがログインしていない場合はイベントを無視します
  • ユーザーがログインするときにFirebaseInstanceId.getToken()を確認し、_!= null_の場合はonTokenRefresh()(または直接ロジック)を手動で呼び出します。

このようにして、ユーザーがログインしているときにトークンを処理できます。トークンが使用できない(またはローテーションされている)場合は、後でonTokenRefresh()イベントを受け取ります。

更新(2017年7月3日):コメントの中で、読者は、ユーザーがログインした後にFirebaseInstanceIdService.onTokenRefresh()を呼び出すことができることを思い出しました。

これは正しいです。ユーザーがログインしても、getToken()が以前に呼び出されていなければ、onTokenRefresh()nullを返す可能性があります。

このケースをアプリで処理する必要があります。ほとんどの場合、ユーザーはとにかくアプリを使用できますが、トークンを受け取るまでプッシュ通知を送信することはできません。

onTokenRefresh()が最終的に呼び出されたときに、ユーザーが以前にログインした場合は、トークンをユーザーに関連付けることができます。

16
Diego Giorgini

申し訳ありませんが、それは不可能です。 FirebaseInstanceIdServiceはアプリケーションの起動時に自動的に呼び出され、Tokenを生成します。アプリケーションInstanceに関連していることに注意してください。特定のユーザーとではありません。 1人の特定のユーザーでTokenを保存しようとしている場合(つまり、ユーザーがログインしたときに、そのユーザーのプッシュ通知のためにそのtokenをサーバーデータベースに保存します)。将来直面するバグは、Twoユーザーが1つのアプリケーションを共有する場合Instance、プッシュ通知が間違ったユーザーにプッシュされる可能性があることです..私の主張を理解していただければ幸いです。

3
Usman lqbal

Gcmトークンがサーバーに送信されたかどうかを示す1つのフラグを共有設定で維持しています。スプラッシュ画面で、1つのメソッドsendDevicetokenToServerを呼び出すたびに。このメソッドは、ユーザーIDが空でないかどうかを確認し、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);

}
0