Firebase:如何让 Android 用户保持登录状态?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22262463/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:44:13  来源:igfitidea点击:

Firebase: How to keep an Android user logged in?

androidfirebasefirebase-security

提问by Neil

I'm using Firebase SimpleLogin to enable Email / Password authentication. Creation of users and subsequent login is all working fine. However, whenever I leave the app (even if only for a few seconds) the user is never logged in on my return i.e...

我正在使用 Firebase SimpleLogin 来启用电子邮件/密码身份验证。创建用户和随后的登录一切正常。但是,每当我离开应用程序时(即使只有几秒钟),用户永远不会在我返回时登录,即..

authClient.checkAuthStatus(new SimpleLoginAuthenticatedHandler())...

Always returns a null user.

始终返回空用户。

I am not logging out the user via the API. Also I have set the number of days the user is logged in to 21 in the Firebase console.

我没有通过 API 注销用户。此外,我在 Firebase 控制台中将用户登录的天数设置为 21。

I have seen mention of a remember-me param in the JS docs, but I can't see any equivalent for Android / Java.

我在 JS 文档中看到过一个“remember-me”参数的提及,但我看不到任何 Android/Java 的等价物。

Wondering if I'm missing anything in the docs or if it's not possible for Android?

想知道我是否在文档中遗漏了任何内容,或者 Android 是否不可能?

Thanks for your help,

谢谢你的帮助,

Neil.

尼尔。

Edit: Added code sample.

编辑:添加了代码示例。

User creation....

用户创建....

public void registerUserForChat(final MyApplication application, String email, String password) {
    Firebase ref = new Firebase(FIREBASE_URL);
    SimpleLogin authClient = new SimpleLogin(ref);
    authClient.createUser(email, password, new SimpleLoginAuthenticatedHandler() {
        @Override
        public void authenticated(com.firebase.simplelogin.enums.Error error, User user) {
            if(error != null) {
                Log.e(TAG, "Error attempting to create new Firebase User: " + error);
            }
            else {
                Log.d(TAG, "User successfully registered for Firebase");
                application.setLoggedIntoChat(true);
            }
        }
    });
}

User login....

用户登录....

public void loginUserForChat(final MyApplication application,  String email, String password) {
    Log.d(TAG, "Attempting to login Firebase user...");
    Firebase ref = new Firebase(FirebaseService.FIREBASE_URL);
    final SimpleLogin authClient = new SimpleLogin(ref);
    authClient.checkAuthStatus(new SimpleLoginAuthenticatedHandler() {
        @Override
        public void authenticated(com.firebase.simplelogin.enums.Error error, User user) {
            if (error != null) {
                Log.d(TAG, "error performing check: " + error);
            } else if (user == null) {
                Log.d(TAG, "no user logged in. Will login...");
                authClient.loginWithEmail(email, password, new SimpleLoginAuthenticatedHandler() {
                    @Override
                    public void authenticated(com.firebase.simplelogin.enums.Error error, User user) {
                        if(error != null) {
                            if(com.firebase.simplelogin.enums.Error.UserDoesNotExist == error) {
                                Log.e(TAG, "UserDoesNotExist!");
                            } else {
                                Log.e(TAG, "Error attempting to login Firebase User: " + error);
                            }
                        }
                        else {
                            Log.d(TAG, "User successfully logged into Firebase");
                            application.setLoggedIntoChat(true);
                        }
                    }
                });
            } else {
                Log.d(TAG, "user is logged in");
            }
        }
    });
}

So loginUserForChat method first checks to see if there is a logged in user and, if not, performs the login. Note that every time I start the app, the logging I see is....

因此 loginUserForChat 方法首先检查是否有登录用户,如果没有,则执行登录。请注意,每次我启动应用程序时,我看到的日志都是....

  1. Attempting to login Firebase user...
  2. no user logged in. Will login...
  3. User successfully logged into Firebase
  1. 正在尝试登录 Firebase 用户...
  2. 没有用户登录。将登录...
  3. 用户成功登录 Firebase

If I exit the app, even for a few seconds, and return - I see the same logging.

如果我退出应用程序,即使是几秒钟,然后返回 - 我会看到相同的日志记录。

One thing I noticed is that the call to checkAuthStatusdoes not take any user credentials - I assume it just checks for anylocally logged in user?

我注意到的一件事是对checkAuthStatus的调用不接受任何用户凭据 - 我假设它只是检查任何本地登录的用户?

Much appreciated.

非常感激。

采纳答案by Rob DiMarco

[Engineer at Firebase] In order to transparently handle persistent sessions in the Firebase Simple Login Java client, you need to use the two-argument constructor which accepts an Android context, i.e. SimpleLogin(com.firebase.client.Firebase ref, android.content.Context context)every time you instantiate the Simple Login Java client.

[Firebase 工程师] 为了在 Firebase 简单登录 Java 客户端中透明地处理持久会话,您需要使用接受 Android 上下文的双参数构造函数,即SimpleLogin(com.firebase.client.Firebase ref, android.content.Context context)每次实例化简单登录 Java 客户端时。

See https://www.firebase.com/docs/java-simple-login-api/javadoc/com/firebase/simplelogin/SimpleLogin.htmlfor the full API reference.

有关完整的 API 参考,请参阅https://www.firebase.com/docs/java-simple-login-api/javadoc/com/firebase/simplelogin/SimpleLogin.html

回答by Leenah

Another way - try this code in your onCreate:

另一种方式 - 在您的onCreate

FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
    // User is signed in
    Intent i = new Intent(LoginActivity.this, MainActivity.class);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    startActivity(i);
} else {
    // User is signed out
    Log.d(TAG, "onAuthStateChanged:signed_out");
}

This will keep the user logged in by taking the user to the Main activity directly without stopping at registration activity. so the user will be logged in unless the user click on signout.

这将通过将用户直接带到主活动来保持用户登录,而无需在注册活动中停止。所以除非用户点击退出,否则用户将被登录。

回答by Oleg Belousov

The proper way to do it is to use oAuth authentication:

正确的方法是使用 oAuth 身份验证:

1. The user logs in.
2. You generate an access token(oAuth2).
3. Android app saves the token locally.
4. Each time the comes back to the auth, he can use the token to to log in, unless the token has been revoked by you, or he changed his
password.

Luckily, firebase has an out of the box support for that, docs:

幸运的是,firebase 对此提供了开箱即用的支持,文档:

https://www.firebase.com/docs/security/custom-login.htmlhttps://www.firebase.com/docs/security/authentication.html

https://www.firebase.com/docs/security/custom-login.html https://www.firebase.com/docs/security/authentication.html

回答by rajeev ranjan

You can do this by Using this Approach to escape logi page if User already logged in.

如果用户已经登录,您可以通过使用此方法来退出登录页面。

private FirebaseAuth auth;
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    auth = FirebaseAuth.getInstance();

    if (auth.getCurrentUser() != null) {
        startActivity(new Intent(Login_Activity.this, Home.class));
        finish();
    }
    setContentView(R.layout.activity_login_);