基于Firebase谷歌登录,实现Android视图认证前屏蔽功能
实现基于Firebase谷歌登录的AuthenticatedActivity认证拦截
嗨,我来帮你完成这个AuthenticatedActivity的认证逻辑,确保只有已登录用户能访问受保护的视图,未认证用户会被拦截并引导登录。
1. 完善AuthenticatedActivity的核心认证逻辑
首先我们补全基类的代码,添加FirebaseAuth状态监听、谷歌登录配置,以及用户状态变化的处理逻辑:
public class AuthenticatedActivity extends AppCompatActivity { private final static String TAG = "AuthenticatedActivity"; private static final int RC_SIGN_IN = 123; protected FirebaseUser firebaseUser; private FirebaseAuth auth; private FirebaseAuth.AuthStateListener authStateListener; private GoogleSignInClient googleSignInClient; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 初始化FirebaseAuth实例 auth = FirebaseAuth.getInstance(); // 配置谷歌登录选项(记得替换成你的web client id) GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken(getString(R.string.default_web_client_id)) .requestEmail() .build(); googleSignInClient = GoogleSignIn.getClient(this, gso); // 初始化认证状态监听器,实时监听用户登录/登出状态 authStateListener = firebaseAuth -> { firebaseUser = firebaseAuth.getCurrentUser(); if (firebaseUser != null) { // 用户已认证,显示页面内容 showAuthenticatedContent(); } else { // 用户未认证,屏蔽内容并引导登录 blockUnauthenticatedAccess(); } }; } @Override protected void onStart() { super.onStart(); // 注册监听器,页面启动时立即检查认证状态 auth.addAuthStateListener(authStateListener); } @Override protected void onStop() { super.onStop(); // 注销监听器,避免内存泄漏 if (authStateListener != null) { auth.removeAuthStateListener(authStateListener); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // 处理谷歌登录返回的结果 if (requestCode == RC_SIGN_IN) { Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data); try { // 谷歌登录成功,获取凭证完成Firebase认证 GoogleSignInAccount account = task.getResult(ApiException.class); firebaseAuthWithGoogle(account); } catch (ApiException e) { Log.w(TAG, "Google sign in failed", e); Toast.makeText(this, "登录失败,请重试", Toast.LENGTH_SHORT).show(); } } } // 用谷歌凭证完成Firebase认证 private void firebaseAuthWithGoogle(GoogleSignInAccount acct) { Log.d(TAG, "firebaseAuthWithGoogle:" + acct.getId()); AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null); auth.signInWithCredential(credential) .addOnCompleteListener(this, task -> { if (task.isSuccessful()) { Log.d(TAG, "signInWithCredential:success"); firebaseUser = auth.getCurrentUser(); } else { Log.w(TAG, "signInWithCredential:failure", task.getException()); Toast.makeText(AuthenticatedActivity.this, "认证失败", Toast.LENGTH_SHORT).show(); } }); } // 已认证用户显示页面内容的方法 protected void showAuthenticatedContent() { // 默认显示Activity的根视图,子类可按需重写 View contentView = getContentView(); if (contentView != null) { contentView.setVisibility(View.VISIBLE); } } // 未认证用户的拦截处理 private void blockUnauthenticatedAccess() { // 隐藏页面核心内容 View contentView = getContentView(); if (contentView != null) { contentView.setVisibility(View.GONE); } // 自动启动谷歌登录流程 startGoogleSignIn(); // 也可以替换成显示自定义登录提示布局,让用户手动触发登录 // loginPromptView.setVisibility(View.VISIBLE); } // 启动谷歌登录意图 private void startGoogleSignIn() { Intent signInIntent = googleSignInClient.getSignInIntent(); startActivityForResult(signInIntent, RC_SIGN_IN); } // 子类可重写此方法,指定需要屏蔽/显示的内容视图 protected View getContentView() { return findViewById(android.R.id.content); } }
2. 子类继承基类的使用方式
你的受保护页面只需要继承这个基类,正常编写自己的布局和业务逻辑即可,基类会自动处理认证拦截:
public class ProfileActivity extends AuthenticatedActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_profile); // 这里编写仅已登录用户可访问的逻辑,比如展示用户信息 if (firebaseUser != null) { TextView userName = findViewById(R.id.tv_user_name); userName.setText(firebaseUser.getDisplayName()); } } // 如果你的内容视图不是默认根布局,可重写此方法指定目标视图 @Override protected View getContentView() { return findViewById(R.id.profile_content_container); } }
3. 关键细节说明
- 实时状态监听:使用
AuthStateListener可以实时响应用户登录/登出操作,比如用户在其他页面登出,当前受保护页面会自动触发拦截逻辑。 - 视图屏蔽逻辑:通过控制视图的显示/隐藏,确保未登录用户完全看不到敏感内容,而不是简单跳转页面。
- 谷歌登录配置:记得在Firebase控制台获取
default_web_client_id,并在项目的strings.xml中配置,否则登录会失败。 - 内存防护:在
onStop()中注销监听器,避免Activity销毁后监听器仍然持有引用导致内存泄漏。
4. 可选优化方向
- 添加自定义登录提示布局,代替自动启动登录,给用户更友好的引导。
- 增加登录失败的重试逻辑,比如添加重试按钮。
- 在拦截状态下显示加载动画,避免用户重复触发登录操作。
内容的提问来源于stack exchange,提问作者Filip
相关产品推荐
相关产品推荐

