Implementing Login in Flutter Web (Hummingbird)

Priyanka Tyagi
Flutter Community
Published in
5 min readSep 6, 2019

--

https://flutter-to-fly.firebaseapp.com

Background

In this article, we’ll make use of FirebaseAuth to implement login functionality in Flutter-to-Fly WebApp built using Flutter Web — Hummingbird. Design has been evolved since I wrote my first article about Designing Cross platform Flutter prototype for Landing Page (Web-Hummingbird, Android, iOS). This article focuses on implementing Login functionality in Hummingbird only. Please refer to this youtube video for implementing same login functionality in Android & iOS.

We’ll implement LogIn button shown below:

Please refer to previous related articles below:

  1. Designing Cross platform Flutter prototype for Landing Page
  2. Making Cross-platform Flutter Landing Page Responsive
  3. Using Flutter Themes for Cross-platform Landing Page (Web-Hummingbird, Android, iOS)
  4. Implementing Flutter FactsBot using DialogFlow

Checkout the companion video:

Introduction

In this article, we’ll make our login button work. I’ll use Firebase authentication to implement email and password authentication. First, setup Firebase Project as mentioned here. We need to add configuration details in Flutter app to be able to communicate with Firebase.

We’ll add two more pages to WebApp.

  1. LogIn Page: Clicking on “LogIn” button will take user to LogIn Page where either they can login using their credentials or register. Registering a user creates a user record in FireStore.
  2. User Profile Page: Logged in users can see their display name, profile picture placeholder, and SignOut button. This is only for demonstration purposes, and doesn’t do much at this point.

pubspec.yaml

Following dependencies need to be added to pubspec.yaml to interact with Firebase. Provider package is used for dependency injection and state management.

dependencies:
firebase: any
service_worker: ^0.2.0
googleapis_auth: ^0.2.3+5
provider: any
dependency_overrides:
provider:
git:
url: https://github.com/kevmoo/provider
ref: flutter_web
firebase:
git:
url: https://github.com/FirebaseExtended/firebase-dart

Web entry point: As we know that Flutter Web apps’ entry point is web/main.dart which is compiled to javascript, and referred from web/index.html. Let's checkout code in both files:

web/main.dart:

main() async {
try {
await config();
fb.initializeApp(
apiKey: apiKey,
authDomain: authDomain,
databaseURL: databaseUrl,
storageBucket: storageBucket,
projectId: projectId,
);
await ui.webOnlyInitializePlatform();
app.main();
} on fb.FirebaseJsNotLoadedException catch (e) {
print(e);
}
}

web/index.html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://www.gstatic.com/firebasejs/6.4.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/6.4.0/firebase-firestore.js"></script>
<script src="https://www.gstatic.com/firebasejs/6.4.0/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/6.4.0/firebase-storage.js"></script>
<script defer src="main.dart.js" type="application/javascript"></script>
</head>
<body>
</body>
</html>

Firebase Configuration:

fb.initializeApp needs Firebase App's configuration parameters. We need to add this information in package:firebase/src/assets/config.json file. There's a sample config.json.sample file available for you for reference:

{
"_FYI": "https://firebase.google.com/docs/web/setup",
"_COPY_TO": "config.json",
"API_KEY": "TODO",
"AUTH_DOMAIN" : "TODO",
"DATABASE_URL": "TODO",
"STORAGE_BUCKET": "TODO",
"PROJECT_ID": "TODO",
"MESSAGING_SENDER_ID": "TODO",
"SERVER_KEY": "TODO",
"VAPID_KEY": "TODO",
}

Get parameters from Firebase console for your project, and update values in config.json.

LogIn Page

I’ll not be explaining the UI code in this tutorial. However, please take a look at source code at the end of this article. Feel free to reach out to me if you need explanation with any part.

LogIn Form:

Register Form:

Authenticating using FirebaseAuthService:

FirebaseAuthService is a ChangeNotifier, which means if any sign-in or sign-out happens in this class, all other subscribed classes are notified. I've abstracted all APIs using BaseAuthService.

abstract class BaseAuthService with ChangeNotifier {
Future<User> currentUser();
Future<User> signIn(String email, String password);
Future<User> googleSignIn();
Future<User> updateUser(User user);
Future<User> createUser(
String firstName, String lastName, String email, String password);
Future<void> signOut();
}

FirebaseAuthService extends BaseAuthService:

Checking for a logged-in user: Following code will check-in whether a user is already signed-in. If so, then UserProfilePage is displayed. Otherwise LogInPage is rendered.

return FutureBuilder<User>(
future: Provider.of<FireAuthService>(context).currentUser(),
builder: (context, AsyncSnapshot<User> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.error != null) {
return Text(snapshot.error.toString());
}
if (snapshot.hasData) {
return UserProfilePage(context, snapshot.data);
}
return LogInPage(title: 'Login');
} else {
return Container(
child: CircularProgressIndicator(),
);
}
},
);

User Profile Page

A UserProfilePage displays very basic information about the logged-in user. Right now, it shows: welcoming user with their email used as display name, placeholder for profile picture and sign-out button. Please refer to source code for details of implementing user interface.

Conclusion

We learned how to implement Firebase authentication in Flutter Web / Hummingbird for ‘Login’ button in our demo web app. We overviewed dependencies, and ChangeNotifier responsible for authentication, registering and creating user, and creating a user record in FireStore. Please refer to code below for Web and Native (Android & iOS) implementations.

Keep Fluttering !

Source code

Originally published at https://ptyagicodecamp.github.io on September 6, 2019.

Https://www.twitter.com/FlutterComm

--

--

Priyanka Tyagi
Flutter Community

Tech explorer | Passionate about sharing explorations around software engineering and leadership