Firebase Auth token自动刷新未触发idTokenChanges流事件问题求助
问题根因
Firebase Auth的idTokenChanges()流本身就不会响应token的静默自动刷新事件,该流仅在以下3种场景触发事件:
- 用户完成登录操作
- 用户完成登出操作
- 主动调用
getIdToken(true)强制刷新token
你遇到的手动刷新能触发、1小时自动刷新不触发是完全符合官方设计的,不是你关闭了自动刷新功能,也不是基础配置错误。
最优解决方案
推荐放弃用流监听更新token的方案,改为给GraphQL客户端添加请求拦截器,每次发起请求时动态获取最新token,这种方式可以100%覆盖所有token刷新场景,不会出现授权失败问题,同时避免你现有逻辑每次重建客户端丢失缓存的缺陷。
示例代码如下:
// 仅需初始化一次GraphQLClient,无需每次换token重建 late final GraphQLClient client; void initClient() { // 自定义请求拦截器,每次发请求前自动注入最新token final authInterceptor = Link.function((request, next) async { final currentUser = locator<AuthService>().auth.currentUser; if (currentUser != null) { // getIdToken方法会自动判断token有效性,过期就自动刷新返回新值,未过期直接返回缓存值 final latestToken = await currentUser.getIdToken(); request = request.updateHeaders({ 'X-Auth-Token': latestToken, 'DG-Auth': dotenv.env['KEY']! }); } return next(request); }); final httpLink = HttpLink(dotenv.env['DGRAPH_ENDPOINT']!); client = GraphQLClient( cache: GraphQLCache(), link: authInterceptor.concat(httpLink), ); }
如果你要保留现有流监听方案
如果一定要沿用现在的监听更新逻辑,可以额外做两个优化:
- 保存流订阅实例避免被垃圾回收,同时在组件销毁时取消订阅防止内存泄漏
- 新增定时拉取逻辑,在token默认1小时有效期前主动拉取新token,触发
idTokenChanges流的事件,完成token更新
late StreamSubscription _tokenSub; @override void initState() { super.initState(); _tokenSub = locator<AuthService>().auth.idTokenChanges().listen((user) { if (user != null) { user.getIdToken().then((token) => locator<DgraphApi>().setNewToken(token)); } }); // 新增定时校验逻辑,每55分钟主动拉取一次新token触发流事件 Timer.periodic(const Duration(minutes: 55), (_) async { final user = locator<AuthService>().auth.currentUser; if (user != null) { await user.getIdToken(); } }); } @override void dispose() { _tokenSub.cancel(); super.dispose(); }
内容的提问来源于stack exchange,提问作者alexn62
相关产品推荐
相关产品推荐

