简体   繁体   中英

Flutter Androit | Firebase Authentication Persistance with Firestore

I wan't to persist authentication state of an user registered in Firebase Auth. The user has data in Firestore DB.

My final attempt:

main.dart

@override
  Widget build(BuildContext context) {
    return StreamProvider<AppUser?>.value(
      value: AuthenticationService().user,
      initialData: null,
      child: const ....
    );
  }

home.dart

@override
  Widget build(BuildContext context) {
    var user = Provider.of<AppUser?>(context);
    print(user);
    Home.user = user;
    ...
  }

authentication.dart

class AuthenticationService {
  final FirebaseAuth _auth = FirebaseAuth.instance;
  final FirebaseFirestore _db = FirebaseFirestore.instance;
  final CollectionReference _usersCollection = FirebaseFirestore.instance.collection('users');

  Stream<AppUser?> get user {
    return _auth.authStateChanges().map((firebaseUser) {
      AppUser? user;
      _usersCollection.doc(firebaseUser!.uid).get().then((DocumentSnapshot userSnapshot) {
        user = _toAppUser(firebaseUser, userSnapshot);
      });
      return user;
    });
  }
}

But with this code, the get user is always null, even just afte logging in

So after dozens of changes, the following code is "working":

main.dart

  @override
  Widget build(BuildContext context) {
    cart.cache();
    return const MaterialApp(
      title: 'CharleMi\'App',
      debugShowCheckedModeBanner: false,
      home: Home(),
    );
  }

home.dart

@override
  Widget build(BuildContext context) {
    return StreamBuilder<User?>(
        stream: FirebaseAuth.instance.authStateChanges(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            AuthenticationService.delegate(snapshot.data).then((user) {
              if (user != null) {
                Home.user = user;
              }
            });
          } else if (snapshot.hasError) {
            print(snapshot.error);
          }
          return ....

authentication.dart

static Future<AppUser?> delegate(User? data) async {
    return AuthenticationService()._toAsyncAppUser(data, null);
  }

Future<AppUser?> _toAsyncAppUser(User? user) async {
    AppUser _user = AppUser(uid: user!.uid);
    var exists = await _user.init(); //Return true, get vars from firestore
    if (exists) {
      return _user; //Returned here when logging in (because exists)
    }
    return null;
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM