Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

[firebase_auth]: authStateChanges() never emits null when the user is force-signed-out before the stream is listened to (iOS, macOS, Android)

未关闭
#18,796 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

@JulianPscheid 已经在做这个了。

开始于 2026年10月13日。

  • #18797 来自 @JulianPscheid —— 未关闭

评估

难度
4/5
预计耗时
1-2 天
新手友好度
15/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
停滞
技术栈
android, dart, ios, kotlin, macos, swift

调研方向

Work is already in progress: pull request #18797 is open against this issue, so review or build on it rather than starting a parallel fix. The first-callback handling lives in FLTAuthStateChannelStreamHandler.swift and FLTIdTokenChannelStreamHandler.swift (iOS and macOS) and in AuthStateChannelStreamHandler.kt and IdTokenChannelStreamHandler.kt (Android), with the Dart side in the auth state handlers. Done means a null first callback reaches Dart, a normal signed-in launch is unchanged, and the 'fires once on first initialization' test still passes.

由索引模型根据 Issue 内容生成。

描述

Needs Attention platform: android platform: ios platform: macos plugin: auth reproduced type: bug

Is there an existing issue for this? I have searched the existing issues. #10230 is related, but it covers a running app with no token refresh.

Which plugins are affected? Auth

Which platforms are affected? Android, iOS, macOS

Description

If Firebase Auth signs the user out on its own before the app listens to authStateChanges() or idTokenChanges(), the Dart side never finds out. FirebaseAuth.instance.currentUser keeps returning the old user for the rest of the process, and all three streams keep emitting that user. Calls that need a token fail with [firebase_auth/no-current-user], Firestore rejects every request with permission-denied, and the app stays on its signed-in UI.

The usual trigger is a revoked refresh token, for example after a password change on another device or an Admin SDK revokeRefreshTokens() call. On the next cold start after the cached ID token has expired, the first token refresh fails and the native SDK signs the user out (on Apple it logs [FirebaseAuth][I-AUT000016] Invalid user token detected, user is automatically signed out.). In our app that happened 1 to 5 seconds after launch, which can be before the first authStateChanges() subscription exists.

The Apple and Android stream handlers drop the first native listener callback unconditionally, because Dart already has an initial value (APP_CURRENT_USER from the plugin constants). You can see it in FLTAuthStateChannelStreamHandler.swift and FLTIdTokenChannelStreamHandler.swift (iOS and macOS) and in AuthStateChannelStreamHandler.kt / IdTokenChannelStreamHandler.kt (Android), where initialAuthState makes the first callback return early. If the native user is already nil when the listener is registered, that first callback is the sign-out, and it gets dropped. On Apple no second nil follows, because addStateDidChangeListener only forwards uid changes. Calling signOut() from Dart afterwards doesn't fix it: the native SDK is already signed out, returns early, and sends no event.

This also breaks signing back in. After the user signs out manually and signs in again with the same account, Dart still holds that user, so apps that react to a change of user see nothing new, and navigation after sign-in can stall until the app is restarted.

Windows (firebase_auth_plugin.cpp) and web forward every callback and aren't affected.

Proposed fix: keep dropping the first callback when it carries a user, and forward it when the user is nil. On its own that would give a fresh signed-out app a second null event, which is what the "fires once on first initialization" test guards against (#3628), so the Dart handlers should also skip a null event when currentUser is already null. A normal signed-in launch behaves as before. I'll open a PR with both changes.

Reproducing the issue
  1. Sign in with email/password on macOS, iOS or Android, then quit the app.
  2. Revoke the user's refresh tokens (Admin SDK revokeRefreshTokens(uid), or change the password from another client).
  3. Wait at least an hour so the cached ID token expires.
  4. Launch the app and subscribe to FirebaseAuth.instance.authStateChanges() a few seconds after startup, or after any early call that refreshes the token, such as currentUser!.getIdTokenResult() or a Firestore read.
  5. Expected: the stream emits null and currentUser is null. Actual: the stream emits the old user, currentUser stays non-null, token-dependent calls fail, and the native log shows the automatic sign-out.

We reproduced this on macOS with firebase_auth 6.7.0. With the proposed change, the app gets null and routes to sign-in, and signing in again works without a restart.

Firebase Core version: 4.15.0 (firebase_auth 6.7.0, firebase-ios-sdk 12.19.0, Android firebase-auth 24.2.0)

Flutter Version: 3.44.8 stable

Relevant Log Output
[FirebaseAuth][I-AUT000016] Invalid user token detected, user is automatically signed out.
[FirebaseFirestore][I-FST000001] Listen for query at users/<uid> failed: Missing or insufficient permissions.
FirebaseAuthException: [firebase_auth/no-current-user] No user currently signed in.
主要语言
Dart
星标
9.3k
派生
4.1k
平均合并
2 天 8 小时
30 天内合并 PR
46

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

firebase/flutterfire 的其他 Issue

查看 firebase/flutterfire 的全部 Issue

相似的 Issue

更多 Dart Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。