title: Is Facebook login suitable for use case which requires silent sign in?
body: <p>Currently, we have a use case which requires silent sign in.</p>
  
  <p>In our app, we tend to provide <strong>auto background sync to cloud storage</strong> feature.</p>
  
  <p>User just need to deal with UI login one-time. For rest of the time, he no longer need to deal with UI to sign in explicitly again.</p>
  
  <p>Android app background process will perform silent sign in for him, get the access token, then send the "access token + cloud file" to cloud storage server for authentication and cloud file storage.</p>
  
  <p>We plan to use 3rd party login mechanism like <strong>Google sign-in</strong>, <strong>Facebook login</strong> so that user needs not go through new account creation step.</p>
  
  <p>Such mechanism works pretty well for Google sign-in, as Google provides silent sign in feature.</p>
  
  <h2>Android app which performs Google silent sign in</h2>
  
  <pre><code>public static GoogleSignInClient buildGoogleSignInClient() {
      GoogleSignInOptions signInOptions =
              new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                      .requestIdToken(WENOTE_CLOUD_STORAGE_CLIENT_ID)
                      .requestEmail()
                      .build();
      return GoogleSignIn.getClient(WeNoteApplication.instance(), signInOptions);
  }
  
  GoogleSignInClient googleSignInClient = buildGoogleSignInClient();
  Task&lt;GoogleSignInAccount&gt; task = googleSignInClient.silentSignIn();
  if (task.isSuccessful()) {
      GoogleSignInAccount googleSignInAccount = task.getResult();
      final String idToken = googleSignInAccount.getIdToken();
  
      // Send idToken to server
  }
  </code></pre>
  
  <h2>Back-end code which performs authentication and accept uploaded file</h2>
  
  <pre><code>@app.route('/upload_file', methods = ['POST'])
  def upload_file():
      file = request.files['file']
      user = json.loads(request.form['user'])
      token = user['token']
  
      # https://developers.google.com/identity/sign-in/web/backend-auth
      try:
          # Specify the CLIENT_ID of the app that accesses the backend:
          idinfo = id_token.verify_oauth2_token(token, requests.Request(), constants.CLIENT_ID)
  
          # Or, if multiple clients access the backend server:
          # idinfo = id_token.verify_oauth2_token(token, requests.Request())
          # if idinfo['aud'] not in [CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3]:
          #     raise ValueError('Could not verify audience.')
  
          if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']:
              raise ValueError('Wrong issuer.')
  
          # If auth request is from a G Suite domain:
          # if idinfo['hd'] != GSUITE_DOMAIN_NAME:
          #     raise ValueError('Wrong hosted domain.')
  
          # ID token is valid. Get the user's Google Account ID from the decoded token.
          sub = idinfo['sub']
  </code></pre>
  
  <hr>
  
  <p>However, I was wondering, is Facebook login ever suitable for such use case? According to </p>
  
  <p><a href="https://developers.facebook.com/docs/facebook-login/access-tokens/" rel="nofollow noreferrer">https://developers.facebook.com/docs/facebook-login/access-tokens/</a></p>
  
  <blockquote>
    <p>Short-lived tokens usually have a lifetime of about an hour or two,
    while long-lived tokens usually have a lifetime of about 60 days.</p>
  </blockquote>
  
  <p>Does it mean, after 60 days, the access token from Facebook is no longer valid. I need to pop up this UI to user, in order to perform auto background sync to cloud storage?</p>
  
  <p><a href="https://i.stack.imgur.com/AgLYn.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/AgLYn.png" alt="enter image description here"></a></p>
  
  <p>The code looks as following for sign in involved pop-up UI. But, how about silent sign in without pop up UI in case access token is expired?</p>
  
  <pre><code>private void facebook() {
      callbackManager = CallbackManager.Factory.create();
  
      LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback&lt;LoginResult&gt;() {
          @Override
          public void onSuccess(LoginResult loginResult) {
              AccessToken accessToken = loginResult.getAccessToken();
  
              // Send accessToken to server.
          }
  
          @Override
          public void onCancel() {
          }
  
          @Override
          public void onError(FacebookException error) {
          }
      });
  
  
      LoginManager.getInstance().logInWithReadPermissions(
              this,
              Arrays.asList("email")
      );
  }
  </code></pre>
  
  <p>Is there any way to avoid such UI login as time pass? Or, we should conclude Facebook login is not suitable for use case which requires silent sign in?</p>
  
  <p>Thank you.</p>