1

I am creating a Flutter app that uses Google Authentication in Firebase.

The user can sign in with Google, but I need to keep the user logged in when the user launches the app again.

This is my code for main.dart

import 'package:flutter/material.dart';
import 'login_page.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

  final FirebaseAuth _auth = FirebaseAuth.instance;

  Future<void> _checkUserStatusGoogle() async {
    await Firebase.initializeApp();
    _auth
        .authStateChanges()
        .listen((User user) {
      if (user == null) {
        print('User is currently signed out!');
      } else {
        print('User is signed in!');
      }
    });
  }


  @override
  void initState() {

      Firebase.initializeApp().whenComplete(() {
        _checkUserStatusGoogle().then((value) {
          print('Check done done');

    });
  });
  }


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Login',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: LoginPage(),
    );
  }
}

There is an error when launching the app with this code:

E/flutter (15566): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: [core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()
E/flutter (15566): #0      MethodChannelFirebase.app (package:firebase_core_platform_interface/src/method_channel/method_channel_firebase.dart:118:5)
E/flutter (15566): #1      Firebase.app (package:firebase_core/src/firebase.dart:52:41)
E/flutter (15566): #2      FirebaseAuth.instance (package:firebase_auth/src/firebase_auth.dart:37:47)
E/flutter (15566): #3      new MyApp (package:flutter_faro_turnos/main.dart:10:43)
E/flutter (15566): #4      main (package:flutter_faro_turnos/main.dart:6:23)
E/flutter (15566): #5      _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:233:25)
E/flutter (15566): #6      _rootRun (dart:async/zone.dart:1190:13)
E/flutter (15566): #7      _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter (15566): #8      _runZoned (dart:async/zone.dart:1630:10)
E/flutter (15566): #9      runZonedGuarded (dart:async/zone.dart:1618:12)
E/flutter (15566): #10     _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:225:5)
E/flutter (15566): #11     _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:301:19)
E/flutter (15566): #12     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)

What is wrong in my code?

EDIT:

New main.dart code:

import 'package:flutter/material.dart';
import 'login_page.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';

void main() async {
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  
  final FirebaseAuth _auth = FirebaseAuth.instance;


  Future<void> _checkUserStatusGoogle() async {
    print('User is currently signed out!');
    FirebaseAuth.instance
        .authStateChanges()
        .listen((User user) {
      if (user == null) {
        print('User is currently signed out!');
      } else {
        print('User is signed in!');
      }
    });
  }


  @override
  void initState() {

    print ("estoy en initstate");

      Firebase.initializeApp().whenComplete(() {
        _checkUserStatusGoogle().then((value) {
          print('Check done done');

    });
  });
  }


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Login',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: LoginPage(),
    );
  }
}

New error output:

E/flutter (18393): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized.
E/flutter (18393): If you're running an application and need to access the binary messenger before `runApp()` has been called (for example, during plugin initialization), then you need to explicitly call the `WidgetsFlutterBinding.ensureInitialized()` first.
E/flutter (18393): If you're running a test, you can call the `TestWidgetsFlutterBinding.ensureInitialized()` as the first line in your test's `main()` method to initialize the binding.
E/flutter (18393): #0      defaultBinaryMessenger.<anonymous closure> (package:flutter/src/services/binary_messenger.dart:93:7)
E/flutter (18393): #1      defaultBinaryMessenger (package:flutter/src/services/binary_messenger.dart:106:4)
E/flutter (18393): #2      MethodChannel.binaryMessenger (package:flutter/src/services/platform_channel.dart:145:62)
E/flutter (18393): #3      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:151:35)
E/flutter (18393): #4      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:334:12)
E/flutter (18393): #5      MethodChannel.invokeListMethod (package:flutter/src/services/platform_channel.dart:347:40)
E/flutter (18393): #6      MethodChannelFirebase._initializeCore (package:firebase_core_platform_interface/src/method_channel/method_channel_firebase.dart:30:36)
E/flutter (18393): #7      MethodChannelFirebase.initializeApp (package:firebase_core_platform_interface/src/method_channel/method_channel_firebase.dart:75:13)
E/flutter (18393): #8      Firebase.initializeApp (package:firebase_core/src/firebase.dart:43:25)
E/flutter (18393): #9      main (package:flutter_faro_turnos/main.dart:7:18)
E/flutter (18393): #10     _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:233:25)
E/flutter (18393): #11     _rootRun (dart:async/zone.dart:1190:13)
E/flutter (18393): #12     _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter (18393): #13     _runZoned (dart:async/zone.dart:1630:10)
E/flutter (18393): #14     runZonedGuarded (dart:async/zone.dart:1618:12)
E/flutter (18393): #15     _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:225:5)
E/flutter (18393): #16     _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:301:19)
E/flutter (18393): #17     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
E/flutter (18393): 
V/FA      (18393): Inactivity, disconnecting from the service
mvasco
  • 4,965
  • 7
  • 59
  • 120

1 Answers1

9

This line of code is executing in during the construction of MyApp, before any of its methods are called:

final FirebaseAuth _auth = FirebaseAuth.instance

Since initializeApp() hasn't been invoked yet, this fails and throws the exception. You should consider calling initializeApp() during main instead, as shown here. The post gives several options. Personally, I would use main().

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

You only need the one call to initializeApp() when your app starts, so you should also remove the other calls in your code.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • I have removed the line final FirebaseAuth _auth = FirebaseAuth.instance and now the exception isn't thrown, but the function _checkUserStatusGoogle() async is never called – mvasco Oct 04 '20 at 19:43
  • I didn't recommend removing that line. I only recommended moving the calls to initializeApp into main, so that you can safely call FirebaseAuth.instance anywhere you want in MyApp. – Doug Stevenson Oct 04 '20 at 19:47
  • I have published as edit the new code for main.dart and also the new error output. – mvasco Oct 04 '20 at 19:52
  • Edited answer. There was a line missing. – Doug Stevenson Oct 04 '20 at 20:03
  • Yes, thank you for your update. Error is gone, but initstate() is not executed, what is missing there? – mvasco Oct 04 '20 at 20:09
  • If you have a new problem, please post it separately. Stack Overflow is not meant for going back and forth on a series of errors. – Doug Stevenson Oct 04 '20 at 20:17