如何处理用户在之前 运行 时使用 Firebase 登录的应用的冷启动

How deal with cold start of an app where user has beeing logged with Firebase at previous run

感谢 Firebase,用户可以在 G+、Facebook 或 Twitter 的帮助下登录。当他们被记录时,一切都很好。

当 Android 应用程序关闭并重新打开时,如何使用 Firebase API 重新启用先前成功登录的用户。应用程序演示和文档中均未解释。

以Facebook为例,sdk似乎保存了token,这就是按钮处于连接状态(显示可以断开连接)的原因。但是 Firebase 和其他身份验证系统呢?

您需要添加一个 AuthStateListenerFirebase documentation on Monitoring Authentication 中对此进行了描述。从那里:

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

对于 Android 上与 Firebase 身份验证相关的任何内容,dedicated demo app 是一个很好的下一站。但一定要先阅读文档,就文档而言,它们还不错。

感谢@Frank-van-Puffelen 的回答,我进行了一些试验,直到我得到相关的东西(至少对我而言:欢迎评论改进)。

我将我的 OAuth 架构分为 3 个主要组件: fdsfds

  1. 位于应用程序中的单个 AuthStateListener。
  2. 一个处理所有身份验证过程的 Utils Singleton OAuthManager
  3. 一个或多个处理身份验证用户交互的活动(登录按钮等)

申请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

这是处理身份验证的每个服务(部分已从 Firebase 专用演示 activity 复制)

SignInActivity

这里只保留处理UI交互的部分。

正在检索?

我不确定这是必要的,但具体情况(可能是由于应用程序崩溃或更新),身份验证状态与 Firebase|Prefs|FacebookSdk 不同。有时间再看。

创建一个 BaseActivity class 并确保应用中的所有其他 Activity 扩展该 class。如果 AuthListener 的 authData 为空,则使用 'instanceOf' 将用户发送到 LoginActivity。

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

}

是的,我也遇到了这个问题,但是关于这个问题的快速更新,你不能使用(如果我错了请纠正我):

Firebase ref 

再说了,你应该做的是声明为全局

private FirebaseAuth mAuth;

然后在侦听器上使用此对象:

 mAuth = FirebaseAuth.getInstance();

只有在那之后你才能使用监听器

  mAuth.addAuthStateListener(mAuthListener);