问题
Thank to Firebase the user can logged with the help of G+, Facebook or Twitter. When they are logged, everything is fine.
When the Android app is closed and re-opened, how to reenable the previous succeed logged user with the Firebase API. It is not explained neither in the app demo or in the documentation.
For exemple for Facebook, the sdk seems to save the token, that 's why the button is at connected state (showing that you can disconnect). But what about Firebase and for other authentication systems.
回答1:
Thanks to the @Frank-van-Puffelen answer, I had some trials until I get something relevant (at least for me : comment are welcome to improve).
I have based my OAuth architecture into 3 mains components : fdsfds
- One single AuthStateListener that is located in the Application.
- One Utils Singleton OAuthManager that deal with all authentication process
- One or Many Activities that deals with Authentification user interaction (Signin Buttons and so on)
Application Class
FacebookSdk.sdkInitialize(this);
Firebase.setAndroidContext(this);
Firebase.getDefaultConfig().setLogLevel(Logger.Level.DEBUG);
Firebase.getDefaultConfig().setPersistenceEnabled(true);
Firebase ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.addAuthStateListener(new Firebase.AuthStateListener() {
@Override
public void onAuthStateChanged(AuthData authData) {
if (authData != null) {
// user is logged in
// create a partialUser from authData
OAuthManager.getDefault().setAuthenticatedUser(authData);
// fetch, merge and save back the partialUser with server registerUser.
OAuthManager.getDefault().startFetchingUserInfo();
} else {
// user is not logged in
// Try to retrieve the user from Facebook SDK
// Try to retrieve the user from "Token and Id save in Android Preferences (in case of issue, or cache reset from Firebase))
// In retrieve is not possible, clean auth data
OAuthManager.getDefault().retrieveOAuth(MilleZimU.getInstance());
}
}
});
OAuthManager
Here is every services that deal with authentication (part has been copy from the Firebase dedicated demo activity)
SignInActivity
Here only remain the part that deal with UI interaction.
Retreiving ?
I'm not sure this is necessary, but case to case (maybe due to crash or update of the app), authentication status where different from Firebase|Prefs|FacebookSdk. I will see with time.
回答2:
You'll need to add a AuthStateListener
. This is described in the Firebase documentation on Monitoring Authentication. From there:
Firebase ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.addAuthStateListener(new Firebase.AuthStateListener() {
@Override
public void onAuthStateChanged(AuthData authData) {
if (authData != null) {
// user is logged in
} else {
// user is not logged in
}
}
});
For anything related to Firebase Authentication on Android, the dedicated demo app is a great next stop. But be sure to first read the documentation, they're not half bad as far as docs go.
回答3:
Create a BaseActivity class and make sure all other Activities in the app extends that class. The use 'instanceOf' to send user to LoginActivity if authData is null from AuthListener.
package com.mabiri.mabiristores;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.firebase.client.AuthData;
import com.firebase.client.Firebase;
import com.mabiri.mabiristores.login.CreateAccount2Activity;
import com.mabiri.mabiristores.login.CreateAccountActivity;
import com.mabiri.mabiristores.login.LoginActivity;
import com.mabiri.mabiristores.login.MapsActivity;
import com.mabiri.mabiristores.utils.Utils;
public class BaseActivity extends AppCompatActivity {
protected Firebase.AuthStateListener mAuthListener;
protected Firebase mFirebaseRef;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFirebaseRef = new Firebase(YOUR_FIREBASE_URL);
if (!((this instanceof LoginActivity) || (this instanceof CreateAccountActivity)
|| (this instanceof CreateAccount2Activity) || (this instanceof MapsActivity))) {
mAuthListener = new Firebase.AuthStateListener() {
@Override
public void onAuthStateChanged(AuthData authData) {
/* The user has been logged out */
if (authData == null) {
//Stop services and clear sharedPreferences if any
/*Take user to login screen*/
takeUserToLoginScreenOnUnAuth();
}
}
};
mFirebaseRef.addAuthStateListener(mAuthListener);
}
}
@Override
protected void onResume() {
super.onResume();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
super.onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
/* Inflate the menu; this adds items to the action bar if it is present. */
getMenuInflater().inflate(R.menu.menu_base, menu);
return true;
}
private void takeUserToLoginScreenOnUnAuth() {
/** Move user to LoginActivity, and remove the backstack */
Intent intent = new Intent(BaseActivity.this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
}
protected void logout() {
/**Unauthenticate user from firebase*/
mFirebaseRef.unauth();
}
/**
* Show error toast to users
*/
protected void showErrorToast(Context context, String message) {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
}
回答4:
Yup I have struggle with this as well, but a quick update on this issue, you cannot use the (and please correct me if i'm wrong):
Firebase ref
anymore, what you should do is declare as a global
private FirebaseAuth mAuth;
and then use this object on the listener:
mAuth = FirebaseAuth.getInstance();
and only after that you can use the listener
mAuth.addAuthStateListener(mAuthListener);
来源:https://stackoverflow.com/questions/32904910/how-deal-with-cold-start-of-an-app-where-user-has-beeing-logged-with-firebase-at