1
votes

I am a bit new to flutter/Firebase and I am trying to get a list of documents from within a sub collection of the logged in users collection. Currently with the code I have it returns null for the logged in user print statement within the stream, however if I pass in the userid manually (instead of passing uid) it works.

database.dart

class DatabaseService {
  final String uid;
  DatabaseService({this.uid});


  // list from snapshot
  List<Item> _ListFromSnapshot(QuerySnapshot snapshot) {
    print(snapshot.documents);
    return snapshot.documents.map((doc) {
      return Item(
        name: doc.data['name'] ?? '',
      );
    }).toList();
  }

  Stream<List<Item>> get items {
    print('current logged in user $uid');
    return Firestore.instance
        .collection('users')
        .document(uid)
        .collection('items')
        .snapshots()
        .map(_ListFromSnapshot);
  }

}

home.dart

class Home extends StatelessWidget {
  final AuthService _auth = AuthService();
  @override
  Widget build(BuildContext context) {
    return StreamProvider<List<Item>>.value(
      value: DatabaseService().items,
      child: Scaffold(
        backgroundColor: Colors.brown[50],
        appBar: AppBar(
          title: Text('MyApp'),
        ),
        // just a widget that uses a listview builder to make a card for each item.
        body: ItemList(),
      ),
    );
  }
}

auth.dart

class AuthService {
  final FirebaseAuth _auth = FirebaseAuth.instance;

  // create user obj based on FirebaseUser
  User _userFromFirebaseUser(FirebaseUser user) {
    return user != null ? User(uid: user.uid) : null;
  }

  // auth change user stream
  Stream<User> get user {
    return _auth.onAuthStateChanged
        .map(_userFromFirebaseUser);
  }
}

I have a feeling it's something to do with the value of uid not be available by the time the app calls it (something future or await/async related). If I figure it out I'll be sure to post back here. Thanks again for taking the time to look.

1
Hi @Rockingoutt93 yes, you are correct, it's related to the Future and async parts of the call. In your function to retrieve the users, you need to use them as the Future type with async set in the declaration. Could you please take a look at these posts here and here to confirm if this helps you?gso_gabriel
Please, let me know how it went @Rockingoutt93gso_gabriel
Thanks I ended up going with a much different approach by using a FutureBuilder instead. And specifying the following in my Future function so that I can include the user id inside of the path: FirebaseUser user = await _auth.currentUser();Rockinoutt

1 Answers

0
votes

Ended up going with a FutureBuilder instead and was able to create a function like the following:

Future<List<T>> getDocs() async {
    final Firestore _db = Firestore.instance;
    FirebaseUser user = await _auth.currentUser();

    if (user != null) {
      ref = _db.collection('users/${user.uid}/items');
    } else {
      return null;
    }
  }