App state change after login but before loading user info from firestore

Viewed 322

I'm using firebase as my backend and each user has a userData document. After the user logs in fire firebase Auth another query is sent to the server to get the user's info and fetch his home feed, however after logging in the app state changes and the home feed is displayed before the query of getting the user's info is completed, and I'm stuck with an exception that some variables are null because I couldn't get them in time. I'm using a streamProvider on _firebaseAuth.authStateChanges() to check if the user is logged in or not.
this is the code I use to authenticate users, and language is the necessary variable needed to know what documents to fetch on the home screen.

UserCredential userCredential = await _firebaseAuth
          .signInWithEmailAndPassword(email: email, password: password);
User user = userCredential.user;
DocumentSnapshot snapshot =
          await DatabaseServices().getUserData(user.uid);
await UserPreferences()
          .setUser(snapshot['username'], email, snapshot['language']);

I'm using SharedPreferences to store user's data, thought I'd mention.
And lastly this is my provider code

Provider<Authentication>(
  create: (_) => Authentication(FirebaseAuth.instance),
),
StreamProvider(
  create: (context) => context.read<Authentication>().authStateChanges,
  initialData: null,
),
final firebaseUser = context.watch<User>();
if (firebaseUser != null) {
  return Home();
}
return LoginPage();

this is the code my home feed

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:you/Firebase/databaseServices.dart';
import 'package:you/Notifiers/HomePostNotifier.dart';

import '../CustomWidgets/PostWidget.dart';

class Feed extends StatefulWidget {
  @override
  _FeedState createState() => _FeedState();
}

class _FeedState extends State<Feed> {
  ScrollController _scrollController = new ScrollController();
  final int _pageLimit = 10;
  bool hasMore = true;
  bool isLoading = false;

  Future getFeed(HomePostNotifier feedNotifier) async {
    hasMore = true;
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String language = prefs.getString('language');
    await DatabaseServices().getHomeFeed(feedNotifier, language, _pageLimit);
  }

  Future loadMorePosts(HomePostNotifier notifier) async {
    if (!hasMore) {
      return;
    }
    if (isLoading) {
      return;
    }
    isLoading = true;
    int size = await DatabaseServices().getMorePosts(notifier, _pageLimit);
    if (size < _pageLimit) {
      hasMore = false;
    }
    isLoading = false;
  }

  @override
  void initState() {
    HomePostNotifier feedNotifier =
        Provider.of<HomePostNotifier>(context, listen: false);
    getFeed(feedNotifier);
    _scrollController.addListener(() {
      double maxScroll = _scrollController.position.maxScrollExtent;
      double currentScroll = _scrollController.position.pixels;
      double delta = MediaQuery.of(context).size.height * 0.25;

      if (maxScroll - currentScroll <= delta) {
        loadMorePosts(feedNotifier);
      }
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    HomePostNotifier feedNotifier = Provider.of<HomePostNotifier>(context);

    return Scaffold(
      backgroundColor: Color.fromRGBO(250, 250, 250, 1),
      appBar: AppBar(
        automaticallyImplyLeading: false,
        backgroundColor: Colors.blue,
        backwardsCompatibility: false,
        systemOverlayStyle: SystemUiOverlayStyle(
          statusBarColor: Colors.blue,
          statusBarIconBrightness: Brightness.light,
          systemNavigationBarColor: Colors.white,
          systemNavigationBarIconBrightness: Brightness.dark,
        ),
        title: Text(
          'You',
          style: TextStyle(
              fontFamily: GoogleFonts.pinyonScript().fontFamily,
              fontWeight: FontWeight.bold,
              fontSize: 28),
        ),
      ),
      body: feedNotifier.homePostList.isEmpty
          ? Center(
              child: CircularProgressIndicator(
              color: Colors.blue,
            ))
          : RefreshIndicator(
              onRefresh: () => getFeed(feedNotifier),
              backgroundColor: Colors.white,
              child: feedNotifier.homePostList.length == 0
                  ? SingleChildScrollView(
                      physics: AlwaysScrollableScrollPhysics(),
                      child: Container(
                        width: MediaQuery.of(context).size.width,
                        height: MediaQuery.of(context).size.height -
                            AppBar().preferredSize.height -
                            kBottomNavigationBarHeight * 2,
                        alignment: Alignment.center,
                        child: Text(
                          "No posts yet. \nBe the first to break the ice :)",
                          textAlign: TextAlign.center,
                          style: TextStyle(
                            fontSize: 22,
                            color: Colors.grey,
                          ),
                        ),
                      ),
                    )
                  : ListView.builder(
                      controller: _scrollController,
                      key: const PageStorageKey<String>('Home feed indicator'),
                      itemBuilder: (BuildContext context, int index) {
                        return PostWidget(
                            index: index,
                            content: feedNotifier.homePostList[index].content,
                            username: feedNotifier.homePostList[index].username,
                            areCommentsAllowed: feedNotifier
                                .homePostList[index].areCommentsAllowed);
                      },
                      itemCount: feedNotifier.homePostList.length,
                    ),
            ),
    );
  }
}

no value is being returned from prefs.getSring() when the user first signs in as I mentioned above, the value of language comes from firestore. If anyone has any suggestion on how to fix it I would greatly appreciate it, thanks in advance.

0 Answers
Related