11

Suppongo di avere un LoginActivity in cui l'utente può registrarsi o accedere con le credenziali esistenti. Non voglio che lo FirebaseInstanceIdService generi un token, a meno che l'utente non abbia effettuato l'accesso e che venga avviato MainActivity dell'applicazione.Come avviare l'ID servizio FCM solo dopo l'attivazione di una determinata attività?

Grazie

+0

Basta chiamare il FirebaseInstanceId.getInstance(). ControllaToken '()' nel vostro '' onCreate di MainActivity'() '. O ovunque nell'Attività pensi di averne bisogno. –

+0

Secondo i registri, la mia implementazione 'FirebaseInstanceIdService' genera token all'avvio dell'applicazione. C'è un modo per impedirlo? – Bravo

+0

Siamo spiacenti. Sono un po 'confuso.Ti riferisci a 'FirebaseInstanceIdService.onTokenRefresh()'? –

risposta

14

Non si può bloccare FirebaseInstanceIdService.onTokenRefresh() da essere chiamato fino a quando l'utente è connesso

cosa si potrebbe fare in caso d'uso è:.

  • Nel FirebaseInstanceIdService.onTokenRefresh() ignorare l'evento, se l'utente non ha effettuato il login
  • Quando il login utente verifica FirebaseInstanceId.getToken() e se != null chiama onTokenRefresh() (o direttamente la logica) ma nualmente.

In questo modo è possibile elaborare il token quando l'utente è loggato, e se il token non è disponibile (o viene ruotato) si riceverà l'evento onTokenRefresh() tardi.

Aggiornamento (3 luglio 2017): nei commenti un lettore ha ricordato che FirebaseInstanceIdService.onTokenRefresh() potrebbe essere chiamato dopo il registro utente in

questo è giusto.. Quando l'utente effettua il login, getToken() potrebbe ancora restituire null se non è stato chiamato prima onTokenRefresh().

È necessario inserire questo caso nella tua app. Molto probabilmente l'utente può comunque utilizzare l'app, ma non è possibile inviare una notifica push finché non si riceve il token.

Quando viene infine chiamato onTokenRefresh(), se l'utente esegue il login in precedenza, è possibile associare il token all'utente.

+0

Cosa succede se FirebaseInstanceIdService.onTokenRefresh() viene chiamato dopo che l'accesso utente è una chiamata asincrona? –

+0

Questo può succedere e devi gestire il caso nella tua app. Molto probabilmente l'utente può comunque utilizzare l'app, ma non è possibile inviare una notifica push finché non si riceve il token. Quindi quando si riceve il token è possibile associarlo all'utente che accede prima. (Ho aggiornato anche la risposta) –

+0

che bello ma penso che abbiamo bisogno di cancellare l'istanza e richiamare il metodo 'getInstance()' dopo il login nel caso in cui sia chiamato prima da firebase per ottenere un nuovo token dall'istanza appena generata. –

3

Siamo spiacenti ma non è possibile. FirebaseInstanceIdService chiama automaticamente all'avvio dell'applicazione e genera un Token. Tieni presente che è correlato all'applicazione Instance. Non con un particolare utente. Se si sta tentando di salvare Token con un particolare utente (ovvero quando l'utente ha effettuato l'accesso, si salverà tale token nel server db per la notifica push di quell'utente). Se si sta facendo un errore in futuro si verificherà che se Due utenti condividono un'applicazione Instance quindi la notifica push può essere inviata all'utente sbagliato. Spero che tu abbia capito il mio punto.

+2

Ciao Usmal. Come risolvere questo problema? Forse rimuovendo l'associazione token dall'utente disconnesso sul mio server e aggiungendola all'utente appena connesso ... cosa ne pensi? – Alessandro

+0

@Alessandro sì ho avuto un problema .. ho fatto quello che dici –

+0

Grazie, sto facendo la stessa cosa! :) – Alessandro

0

Sto mantenendo un flag in pref condiviso che indica se il token gcm è stato inviato al server o meno. Nella schermata Splash ogni volta che chiamo un metodo sendDevicetokenToServer. Questo metodo controlla se l'id utente non è vuoto e lo stato di invio gcm quindi invia token al server.

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()); 
      } 
     }); 

    } 

} 

In classe 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); 

}