The problem is you have explicitly made your login page as your homepage. When the app opens, it will automatically read through the main.dart file and see login page as the assigned Homepage.
This is how you fix it. And also make an authentication system where you can get the logged in user's ID at any point in the app.
What you need:
- Provider dependency of whichever version. Preferably the latest
- A smile- Stop frowning. You're about to fix your problem
- Firebase Auth dependency. At whichever version. I'm going to give you a fix
for the newest version, and for decidedly older versions.
Step 0: Add the needed dependencies and run flutter pub get. This one is a no brainer.
Step1: Make an auth_services class:
Code is below
For older versions of firebase auth:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
class AuthService {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
final GoogleSignIn _googleSignIn = GoogleSignIn();
Stream<String> get onAuthStateChanged =>
_firebaseAuth.onAuthStateChanged.map(
(FirebaseUser user) => user?.uid,
);
// GET UID
Future<String> getCurrentUID() async {
return (await _firebaseAuth.currentUser()).uid;
}
}
For newer versions of firebase auth dependency:
class AuthService {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
final GoogleSignIn _googleSignIn = GoogleSignIn();
Stream<User> get onAuthStateChanged => _firebaseAuth.authStateChanges();
// GET UID
Future<String> getCurrentUID() async {
return _firebaseAuth.currentUser.uid;
}
}
Explanation : I have made this class to handle all auth functions. I am making a function called onAuthStateChanged that returns a stream of type User (ids for older versions of firebase auth) and i am going to listen to this stream to find out whether there is a user logged in or not.
Step 2: Create the auth provider that is going to wrap the entire app and make it possible to get our user id anywhere in the app.
Create a file called auth_provider.dart.
The code is below.
import 'package:flutter/material.dart';
import 'auth_service.dart';
class Provider extends InheritedWidget {
final AuthService auth;
Provider({
Key key,
Widget child,
this.auth,
}) : super(key: key, child: child);
@override
bool updateShouldNotify(InheritedWidget oldWiddget) {
return true;
}
static Provider of(BuildContext context) =>
(context.dependOnInheritedWidgetOfExactType<Provider>());
}
The next step is to wrap the entire app in this provider widget and set the home controller as the homepage.
Step 3: On the main.dart file, or anywhere really, make a class called HomeController which will handle the logged in state, and set the home Controller as the assigned homepage.
NB: I have set a container of color black to be shown as the app is loading to determine if a user is logged in or not. It is a fairly fast process but if you want to, you can set it to be container of the theme color of your app. You can even set it to be a splash screen. (Please note. This containeris shown for about 1 second at most. From my experience)
Code is below:
Import all the necessary things
void main() {
//WidgetsFlutterBinding.ensureInitialized();
// await Firebase.initializeApp();
//only add these if you're on the latest firebase
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Provider(
auth: AuthService(),
child: MaterialApp(
title: 'Dreamora',
theme: ThemeData(
// fontFamily: "Montserrat",
brightness: Brightness.light,
inputDecorationTheme: InputDecorationTheme(
contentPadding:
EdgeInsets.only(top: 10, bottom: 10, left: 10, right: 10),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
),
),
primarySwatch: Colors.purple,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomeController(),
);
},
),
),}
//(I think i have messed up the brackets here, but, you get the
//gist)
class HomeController extends StatelessWidget {
const HomeController({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
final AuthService auth = Provider.of(context).auth;
return StreamBuilder(
stream: auth.onAuthStateChanged,
builder: (context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
final bool signedIn = snapshot.hasData;
return signedIn ? DashBoard() : FirstView();
}
return Container(
color: Colors.black,
);
},
);
}
}
Explanation: The home controller is just a steam builder that listens to the steeam of auth changes we made. If there is any stuff, the user is logged in. If not, he is logged out. Fairly simple. There is like a 1 second lag though in between determining a user's logged in state. Soo, i am returning a black container in that time. The user will see the screen turn black for about a second after opening the app and then boom. Homepage
IMPORTANT: You should wrap your entire app with provider. This is important. Do not forget it.
HOW TO GET THE USER ID AT ANY POINT IN THE APP
Provider.of(context).auth.getCurrentUID()
There you go. Enjoy
[EDIT]As L. Gangemi put it, The new version of Firebase Auth returns a stream of users. So edit the home controller code to be
builder: (context, AsyncSnapshot<User> snapshot) {