Flutter Firestore getDocuments() not working on initState

916

I'm guessing here that your code will not always work, because getCurrentPainLevel might get called before getCurrentUser is completed, which will cause _uid to be null and therefore, not work as expected. Try to put then keyword after getCurrentUser method, like this:

@override
  void initState() {
    super.initState();
    getCurrentUser().then((_) {
      getCurrentPainLevel();
    });
  }

By the way, you should NOT be calling async methods in initState. Try to put the code somewhere else, like WidgetsBinding.instance.addPostFrameCallback(...).

Share:
916
Michael
Author by

Michael

Updated on December 21, 2022

Comments

  • Michael
    Michael over 1 year

    I'm having an issue trying to call a document from Firestore in initState. I can pull data from a StreamBuilder just fine, but I just want to call the data once on initState.

    Here is what I'm doing:

    class _PainLevelState extends State<PainLevel> {
      final FirebaseAuth _auth = FirebaseAuth.instance;
      final CollectionReference userCollection =
          Firestore.instance.collection('users');
      static final now = DateTime.now();
      String _uid;
      double myPainLevel = 0;
    
      Future<void> getCurrentUser() async {
        final FirebaseUser user = await _auth.currentUser();
        if (mounted) {
          setState(() {
            _uid = user.uid;
          });
        }
      }
    
      Future<void> getCurrentPainLevel() async {
        await userCollection
            .document(_uid)
            .collection('pain')
            .where('time',
                isGreaterThanOrEqualTo: DateTime(now.year, now.month, now.day))
            .getDocuments()
            .then((QuerySnapshot docs) {
          if (docs.documents.isNotEmpty) {
            print('yes');
          } else {
            print('no'); 
          }
        });
      }
    
      @override
      void initState() {
        super.initState();
        getCurrentUser();
        getCurrentPainLevel();
      }
    
    ...
    

    I just get a "no" every time I print to console. It's not get any documents when there is one. If I take the same code inside the future and put it somewhere else, like in the build method, it works, but it constantly builds and I don't want that. Any suggestion as to why it is not working? Thanks in advance.

  • Michael
    Michael almost 4 years
    That makes sense now. Thank you! I changed the initState to WidgetsBinding.instance.addPostFrameCallback((_) => getCurrentPainLevel()); and just added final FirebaseUser user = await _auth.currentUser(); to the getCurrentPainLevel() method, and changed _uid to user.uid. It works now. :)