You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter切换账号后UserProvider未根据pending值更新UI问题

问题原因
  1. UserProvider中userid未动态更新:String userid = Auth().currentUser!.uid;是在类实例化时赋值的,切换账号后这个值不会自动更新为新用户的UID,导致fetchUser仍获取旧用户的数据。
  2. 注销后状态未重置:注销账号时,UserProvider的_user没有被重置为null,UI仍会显示旧用户的pending状态。
  3. 新登录后未触发数据刷新:切换账号登录后,没有主动调用fetchUser获取新用户的Firestore数据。
解决方案

1. 修改UserProvider代码

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:our_voice/modules/user.dart';
import 'package:our_voice/services/auth.dart';

class UserProvider extends ChangeNotifier {
  User? _user;
  User? get user => _user;

  // 改为动态获取当前用户UID
  String get userid => Auth().currentUser?.uid ?? '';

  Future<void> fetchUser() async {
    if (userid.isEmpty) return;
    final snapshot = await FirebaseFirestore.instance.collection('users').doc(userid).get();
    _user = User.fromFirestore(snapshot);
    notifyListeners();
  }

  // 添加重置用户状态的方法,注销时调用
  void resetUser() {
    _user = null;
    notifyListeners();
  }
}

2. 处理注销逻辑

在执行注销操作的地方,调用UserProvider的resetUser方法:

// 示例注销按钮逻辑
ElevatedButton(
  onPressed: () async {
    await Auth().signOut();
    // 获取UserProvider实例并重置状态
    Provider.of<UserProvider>(context, listen: false).resetUser();
    // 跳转到登录页等后续操作
  },
  child: const Text('注销'),
)

3. 新登录后触发数据刷新

在登录成功后,调用fetchUser获取新用户数据:

// 示例登录成功后的逻辑
await Auth().signInWithEmailAndPassword(email, password);
// 获取UserProvider实例并刷新用户数据
Provider.of<UserProvider>(context, listen: false).fetchUser();
// 跳转到MainPage

4. 可选优化:监听Auth状态自动刷新

如果希望自动监听用户登录/注销状态并更新数据,可以在UserProvider中添加监听:

class UserProvider extends ChangeNotifier {
  User? _user;
  User? get user => _user;
  StreamSubscription? _authSubscription;

  UserProvider() {
    // 监听Auth状态变化,自动更新用户数据
    _authSubscription = Auth().authStateChanges.listen((firebaseUser) {
      if (firebaseUser != null) {
        fetchUser();
      } else {
        resetUser();
      }
    });
  }

  @override
  void dispose() {
    _authSubscription?.cancel();
    super.dispose();
  }

  Future<void> fetchUser() async {
    final uid = Auth().currentUser?.uid;
    if (uid == null) return;
    final snapshot = await FirebaseFirestore.instance.collection('users').doc(uid).get();
    _user = User.fromFirestore(snapshot);
    notifyListeners();
  }

  void resetUser() {
    _user = null;
    notifyListeners();
  }
}

添加此监听后,用户登录/注销时,UserProvider会自动触发数据刷新,无需手动调用fetchUser或resetUser。

验证效果
  1. 注销账号:UserProvider的_user被重置为null,MainPage的悬浮按钮会显示空Container。
  2. 用另一个账号登录:UserProvider会获取新用户的Firestore数据,pending值更新后,UI会根据新值渲染对应的悬浮按钮。

内容的提问来源于stack exchange,提问作者Aymen Ziouche

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:03:15