AsyncValue类型无registerUser方法报错及路由重定向与持久化需求
一、报错原因
你的registrationRepoProvider是FutureProvider,调用ref.watch(registrationRepoProvider)返回的是**AsyncValueRegistrationRepo实例,因此无法直接调用registerUser方法。
二、分步解决方案
1. 修复 AsyncValue 调用问题
在redirect函数中,通过await ref.watch(registrationRepoProvider.future)获取实际的RegistrationRepo实例,替代原有的直接watch:
redirect: (context, state) async { final currentUser = authRepository.currentUser; if (currentUser == null) { return '/signIn'; } // 获取真实的RegistrationRepo实例,解决AsyncValue报错 final registrationRepo = await ref.watch(registrationRepoProvider.future); // ...后续逻辑 }
2. 集成 SharedPreferences 持久化
添加缓存逻辑,避免每次路由跳转都调用API,实现状态持久化:
步骤1:定义用户专属缓存Key
用用户UID作为缓存Key的一部分,保证不同用户的状态独立存储:
final userRegisteredKey = 'user_registered_${currentUser.uid}'; final businessRegisteredKey = 'business_registered_${currentUser.uid}';
步骤2:缓存优先的状态判断逻辑
先从SharedPreferences读取缓存状态,缓存不存在时再调用API,然后将结果写入缓存:
redirect: (context, state) async { final currentUser = authRepository.currentUser; if (currentUser == null) { return '/signIn'; } // 获取RegistrationRepo实例 final registrationRepo = await ref.watch(registrationRepoProvider.future); // 初始化SharedPreferences final prefs = await SharedPreferences.getInstance(); // 定义缓存Key final userRegisteredKey = 'user_registered_${currentUser.uid}'; final businessRegisteredKey = 'business_registered_${currentUser.uid}'; // 处理用户注册状态:先读缓存,无缓存则调用API并写入 bool? isUserRegistered = prefs.getBool(userRegisteredKey); if (isUserRegistered == null) { isUserRegistered = await registrationRepo.registerUser(currentUser.uid); await prefs.setBool(userRegisteredKey, isUserRegistered); } // 处理商业注册状态:同用户注册逻辑 bool? isBusinessRegistered = prefs.getBool(businessRegisteredKey); if (isBusinessRegistered == null) { isBusinessRegistered = await registrationRepo.registerBusiness(currentUser.uid); await prefs.setBool(businessRegisteredKey, isBusinessRegistered); } // 路由跳转逻辑 if (!isUserRegistered) { return '/setup/personal'; } else if (!isBusinessRegistered) { return '/setup/business'; } else { return '/home'; } },
3. 注册成功后更新缓存
在个人注册(AccountSetupScreen)和商业注册(BusinessSetupScreen)完成后,需要手动更新缓存,确保下次路由跳转状态正确:
例如在AccountSetupScreen的注册成功回调中:
// 注册成功后更新用户注册状态缓存 final prefs = await SharedPreferences.getInstance(); await prefs.setBool('user_registered_${currentUser.uid}', true);
在BusinessSetupScreen的注册成功回调中:
// 注册成功后更新商业注册状态缓存 final prefs = await SharedPreferences.getInstance(); await prefs.setBool('business_registered_${currentUser.uid}', true);
三、完整修改后的 app_router.dart 核心代码
@riverpod GoRouter goRouter(GoRouterRef ref) { final authRepository = ref.watch(firebaseAuthRepositoryProvider); return GoRouter( initialLocation: "/signIn", debugLogDiagnostics: true, refreshListenable: GoRouterRefreshStream(authRepository.authStateChanges()), redirect: (context, state) async { final currentUser = authRepository.currentUser; if (currentUser == null) { return '/signIn'; } // 获取RegistrationRepo实例 final registrationRepo = await ref.watch(registrationRepoProvider.future); // 初始化SharedPreferences final prefs = await SharedPreferences.getInstance(); // 缓存Key定义 final userRegisteredKey = 'user_registered_${currentUser.uid}'; final businessRegisteredKey = 'business_registered_${currentUser.uid}'; // 处理用户注册状态 bool? isUserRegistered = prefs.getBool(userRegisteredKey); if (isUserRegistered == null) { isUserRegistered = await registrationRepo.registerUser(currentUser.uid); await prefs.setBool(userRegisteredKey, isUserRegistered); } // 处理商业注册状态 bool? isBusinessRegistered = prefs.getBool(businessRegisteredKey); if (isBusinessRegistered == null) { isBusinessRegistered = await registrationRepo.registerBusiness(currentUser.uid); await prefs.setBool(businessRegisteredKey, isBusinessRegistered); } // 路由跳转 if (!isUserRegistered) { return '/setup/personal'; } else if (!isBusinessRegistered) { return '/setup/business'; } else { return '/home'; } }, // ...原有路由配置 ); }
内容的提问来源于stack exchange,提问作者Nikhita Watpal
相关产品推荐
相关产品推荐

