'Flutter Google Sign in, Endless loading Icon when selecting an existing account

I get endless loading Icon when selecting an existing account

I can create an account just fine for the first time and login, but when i close android studio then restart main.dart & emulator then try to sign in to that existing account, i get infinite loading icon :

enter image description here

Here's the loginPage.dart code:-

import 'dart:async';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:telegramchatapp/Pages/HomePage.dart';
import 'package:telegramchatapp/Widgets/ProgressWidget.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:shared_preferences/shared_preferences.dart';


class LoginScreen extends StatefulWidget {

  LoginScreen({Key key}) : super(key : key);

  @override
  LoginScreenState createState() => LoginScreenState();
}



class LoginScreenState extends State<LoginScreen> {

  final GoogleSignIn googleSignIn = GoogleSignIn();
  final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
  SharedPreferences preferences;

  bool isLoggedIn = false;
  bool isLoading = false;
  FirebaseUser currentUser;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    isSignedIn();
  }

  void isSignedIn() async{
    this.setState(() {
      isLoggedIn = true;
    });

    preferences = await SharedPreferences.getInstance();
    isLoggedIn = await googleSignIn.isSignedIn();

    if(isLoggedIn){
      Navigator.push(context, MaterialPageRoute(builder: (context) => HomeScreen(currentUserId: preferences.getString("id"))));
    }

    this.setState(() {
      isLoading = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        decoration: BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.topRight,
            end: Alignment.bottomLeft,
            colors: [Colors.blueAccent, Colors.black12],
          ),
        ),
        alignment: Alignment.center,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Text(
              "Solef App",
              style: TextStyle(fontSize: 82.0, color: Colors.white, fontFamily: "Signatra"),
            ),
            GestureDetector(
              onTap: controlSignIn,
              child: Center(
                child: Column(
                  children: <Widget>[
                    Container(
                      width: 270.0,
                      height: 65.0,
                      decoration: BoxDecoration(
                        image: DecorationImage(
                          image: AssetImage(
                              "assets/images/google_signin_button.png"),
                        ),
                      ),
                    ),
                    Padding(
                      padding: EdgeInsets.all(1.0),
                      child: isLoading ? circularProgress() : Container(),
                    ),
                  ],
                ),
              ),
            )
          ],
        ),
      ),
    );
  }


  Future<Null> controlSignIn() async {

    preferences = await SharedPreferences.getInstance();

    this.setState(() {
      isLoading = true;
    });

    /*GoogleSignIn _googleSignIn = GoogleSignIn(
      scopes: [
        'email',
        'https://www.googleapis.com/auth/contacts.readonly',
      ],
    );*/
    
    GoogleSignInAccount googleUser = await googleSignIn.signIn();
    GoogleSignInAuthentication googleAuthentication = await googleUser.authentication;
    
    final AuthCredential credential = GoogleAuthProvider.getCredential(idToken: googleAuthentication.idToken, accessToken: googleAuthentication.accessToken);

    FirebaseUser firebaseUser = (await firebaseAuth.signInWithCredential(credential)).user;

    //SignIn Success
    if(firebaseUser != null){
      //check if already signup
      final QuerySnapshot resultQuery = await Firestore.instance.collection("users").where("id", isEqualTo: firebaseUser.uid).getDocuments();
      final List<DocumentSnapshot> documentSnapshots = resultQuery.documents;

      //save data to firestore - if new user
      if(documentSnapshots.length == 0){
        Firestore.instance.collection("users").document(firebaseUser.uid).setData(
            {
              "nickname": firebaseUser.displayName,
              "photoUrl": firebaseUser.photoUrl,
              "id": firebaseUser.uid,
              "aboutMe": "I'm using SOLEF chat app.",
              "createdAt": DateTime.now().millisecondsSinceEpoch.toString(),
              "chatingWith": null,
            });
          //write data to Local
          currentUser = firebaseUser;
          await preferences.setString("id", currentUser.uid);
          await preferences.setString("nickname", currentUser.displayName);
          await preferences.setString("photoUrl", currentUser.photoUrl);

      }else{
        //write data to Local
        currentUser = firebaseUser;
        await preferences.setString("id", documentSnapshots[0]["id"]);
        await preferences.setString("nickname", documentSnapshots[0]["nickname"]);
        await preferences.setString("photoUrl", documentSnapshots[0]["photoUrl"]);
        await preferences.setString("aboutMe", documentSnapshots[0]["aboutMe"]);
      }
      Fluttertoast.showToast(msg: "SignIn Successful.");
      this.setState(() {
        isLoading = false;
      });
      
      Navigator.push(context, MaterialPageRoute(builder: (context) => HomeScreen(currentUserId: firebaseUser.uid)));
      
    }
    
    //SignIn Not Success - Failed
    else{
      Fluttertoast.showToast(msg: "Try Again, SignIn Failed.");
      this.setState(() {
        isLoading = false;
      });
    }
  }


}

Here's the Homepage.dart:

import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';


import '../main.dart';


class HomeScreen extends StatefulWidget {

  final String currentUserId;
  HomeScreen({Key key, @required this.currentUserId}) : super(key : key);

  @override
  State createState() => HomeScreenState();
}

class HomeScreenState extends State<HomeScreen> {

  @override
  Widget build(BuildContext context) {
    return RaisedButton.icon(onPressed: logoutUser, icon: Icon(Icons.close), label: Text("Sign Out"));
  }

  final GoogleSignIn googleSignIn = GoogleSignIn();

  Future<Null> logoutUser() async{
    await FirebaseAuth.instance.signOut();
    await googleSignIn.disconnect();
    await googleSignIn.signOut();

    Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) => MyApp()), (Route<dynamic> route ) => false);

  }
}


class UserResult extends StatelessWidget
{
  @override
  Widget build(BuildContext context) {

  }
}


Solution 1:[1]

The problem is you're not using the try catch block. For example, you can do something like this:

  Future signInAnon() async {
    setState(() {
      _isLoading = true;
    });
    FirebaseAuth auth = FirebaseAuth.instance;
    try {
      await auth.signInAnonymously();
    } on FirebaseAuthException catch (e) {
      setState(() {
        _isLoading = false;
      });
      showSimpleNotification(
        const Text(
          'Sign In Error',
          style: TextStyle(color: Colors.white),
          textAlign: TextAlign.center,
        ),
        contentPadding: const EdgeInsets.all(12),
        background: Colors.red,
      );
    } catch (e) {
      setState(() {
        _isLoading = false;
      });
    }
  }

Then, on listening to the user signing, you can do this:

class AppWrapper extends StatefulWidget {
  const AppWrapper({Key? key}) : super(key: key);

  @override
  _AppWrapperState createState() => _AppWrapperState();
}


class _AppWrapperState extends State<AppWrapper> {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<User?>(
      stream: FirebaseAuth.instance.authStateChanges(),
      builder: (context, AsyncSnapshot<User?> snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Center(child: CircularProgressIndicator());
        } else if (snapshot.hasError) {
          return errorPage();
        } else if (snapshot.hasData) {
          return const HomePage();
        } else {
          return const SigningPage();
        }
      },
    );
  }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 dev.bojack