Huzzi
Huzzi

Reputation: 571

Flutter Firebase onAuthStateChanged

I'm creating a flutter app using the Firebase authentication and firestore database to store the user profile.

When the user is authenticated I want to grab the user's profile document as a stream and make it available to all the widgets.

This is my code:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
        providers: [
          StreamProvider<FirebaseUser>.value(
              value: FirebaseAuth.instance.onAuthStateChanged),
          StreamProvider<Profile>.value(value: DatabaseService().getProfile()),
        ],
        child: MaterialApp(
          title: 'App Title',
          theme: customTheme(),
          home: Wrapper(),
        ));
  }
}

And inside the DatabaseService I have.

 Stream<Profile> getProfile() {

  final CollectionReference profileCollection =Firestore.instance.collection('profiles');

    Stream<FirebaseUser> user = FirebaseAuth.instance.onAuthStateChanged;

    user.listen((event) {
      profileCollection.document(event.uid).get().then((value) {
        return Profile.fromJson(value.data);
      });
    });

    return null;
  }

The problem is the getProfile method always returns null.

Upvotes: 0

Views: 1211

Answers (2)

Arun Yogeshwaran
Arun Yogeshwaran

Reputation: 451

As per the documentation of get() from profileCollection.document(event.uid).get()

Reads the document referenced by this [DocumentReference].

If no document exists, the read will return null.

If this is the first time authentication, you have to add the document to your collection Firestore.instance.collection('profiles') using

Firestore.instance.collection('profiles').document(user.uid).setData({
        "id": user.uid,
        "username": user.username
});

Then later you can query your collection like

profileCollection.document(user.uid).get().then((value) {
        return Profile.fromJson(value.data);
});

It should not return null then.

Upvotes: 1

Peter Haddad
Peter Haddad

Reputation: 80924

Change the method to the following:

  Future<Profile> getProfile() async* {
    final CollectionReference profileCollection = Firestore.instance.collection('profiles');
    FirebaseUser user = await FirebaseAuth.instance.currentUser();
    var value = await profileCollection.document(user.uid).get();
    return Profile.fromJson(value.data);
  }

currentUser() which returns a Future will give you information about the currently logged in user and then you can get the uid and use it in documents.

Upvotes: 1

Related Questions