有时Provider在flutter中匿名注册后不会触发
Posted
技术标签:
【中文标题】有时Provider在flutter中匿名注册后不会触发【英文标题】:Sometimes Provider doesn't trigger after anonymous sign-up in flutter 【发布时间】:2021-09-25 14:18:56 【问题描述】:你好 Flutter 开发者,
我在使用 Flutter 开发自己的应用程序时遇到了一个错误,这让我的生活变得非常复杂。它是这样的:
-
用户打开应用
如果他们没有登录,他们会被重定向到 USP 页面。
如果他们点击下一步,他们将被重定向到注册页面。
注册由 Firebase 提供,并且是匿名的
如果注册成功,应触发
Provider
并加载新页面
错误是有时用户会被送回 USP 页面(意味着他们的user_id
是null
),尽管在注册期间没有抛出异常。如果我强制导航到登录页面,则用户没有user_id
,这对我来说是个问题。
任何人遇到并解决了同样的问题?下面你可以看到我是如何构建我的代码的,也许这会有所帮助?
这是我的主文件:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
Future<void> main() async
WidgetsFlutterBinding.ensureInitialized();
await SignIn.initializeFirebase();
runApp(MyApp());
class MyApp extends StatelessWidget
getSignInUser()
return SignIn().user;
Widget getMaterialApp()
return MaterialApp(
title: 'app_title',
home: HomePagePicker(),
onGenerateRoute: RouteGenerator.generateRoute,
debugShowCheckedModeBanner: false,
);
@override
Widget build(BuildContext context)
return MultiProvider(
providers: [
StreamProvider<MyUser?>.value(value: SignIn().user, initialData: null),
],
child: getMaterialApp(),
);
class HomePagePicker extends StatefulWidget
@override
_HomePagePickerState createState() => _HomePagePickerState();
class _HomePagePickerState extends State<HomePagePicker>
@override
Widget build(BuildContext context)
MyUser? myUser = Provider.of<MyUser?>(context);
if (myUser == null) return IntroScreen(); // this shows the USPs
else
// this takes you to the signed-in part of the app
return AnotherScreen();
IntroScreen 是一个非常简单的屏幕,带有几个 USP 和一个用于打开注册页面的按钮。它类似于
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'login.dart';
class IntroScreen extends StatelessWidget
static const routeName = '/introScreen';
@override
Widget build(BuildContext context)
analytics.setScreenName("introScreen");
return Scaffold(
body: AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(statusBarColor: ThemeConfig.darkPrimary),
child: Column(...), // show the USPs
floatingActionButton: getFloatingButton(context)
);
Widget getFloatingButton(BuildContext buildContext)
return FloatingActionButton(
backgroundColor: ThemeConfig.primary,
foregroundColor: Colors.white,
child: Icon(Icons.arrow_forward),
onPressed: ()
navigateToScreen(MyLogin.routeName, buildContext, null);
,
);
// this is in another file normally but putting it here for completeness
navigateToScreen(String routeName, BuildContext context, Object? arguments)
Navigator.pushNamed(
context,
routeName,
arguments: arguments
);
注册页面的重点是这个
Future<void> finalizeRegistration(String userName, String userToken) async
await usersCollection.add('userName': userName, "userToken": userToken);
Future<void> registerUser(String userName)
return SignIn()
.anonymousSignIn(userName)
.timeout(Duration(seconds: 2))
.then((userToken)
finalizeRegistration(userName, userToken)
.then((value) => Navigator.pop(context));
)
.catchError((error)
registrationErrorDialog();
);
SignIn 类如下
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:house_party/models/MyUser.dart';
class SignIn
final FirebaseAuth _auth = FirebaseAuth.instance;
static Future<FirebaseApp> initializeFirebase() async
FirebaseApp firebaseApp = await Firebase.initializeApp();
return firebaseApp;
Stream<MyUser?> get user
return _auth
.authStateChanges()
.asyncMap(getUser);
Future<String> anonymousSignIn(String userName) async
var authResult = await _auth.signInAnonymously();
return authResult.user!.uid;
Future<MyUser?> getUser(User? user) async
if (user == null)
return Future.value(null);
return FirebaseFirestore.instance
.collection('users')
.where('userToken', isEqualTo: user.uid)
.get()
.then((res)
if (res.docs.isNotEmpty)
return MyUser.fromFireStore(res.docs.first.data());
else
return null;
);
最后,我正在使用这些版本的 firebase
firebase_core: ^1.0.0
cloud_firestore: ^1.0.0
firebase_dynamic_links: ^2.0.0
firebase_auth: 1.1.2
firebase_analytics: ^8.1.1
我希望问题陈述足够清楚!
提前致谢!
【问题讨论】:
【参考方案1】:我通过如下升级firebase库解决了这个问题(或者至少我不能再重现它了)
firebase_core: ^1.4.0
cloud_firestore: ^2.4.0
firebase_dynamic_links: ^2.0.7
firebase_auth: 3.0.1
firebase_analytics: ^8.2.0
【讨论】:
以上是关于有时Provider在flutter中匿名注册后不会触发的主要内容,如果未能解决你的问题,请参考以下文章
Flutter:如何设置 Stream 和 Provider