Add Firebase to Flutter mobile and web

Praharsh Bhatt
Multiverse Software
6 min readDec 4, 2019

Firebase Authentication (login) and Firestore on Flutter mobile and web

Simple Tutorial for Firebase Authentication (login) and Firestore on Flutter mobile and web

What is Flutter?

Flutter is an open-source mobile SDK developed by Google to build high-quality applications for Android and iOS. It allows developers to not only build an application with beautiful design, smooth animation, and fast performance but also able to integrate new features quickly. Flutter offers high-velocity development with its stateful hot reload and hot restart. With only one code base to manage, you get to save a lot of costs comparing to managing both Android and iOS projects as Flutter compiles it to native ARM code. Flutter uses Dart programming language which is also developed by Google.

What is Firebase?

Firebase is a mobile and web development platform that provides the developer with a wide range of products. Today we will be looking at how we can build our first Flutter application with Firebase authentication and realtime database (RTDB). This application allows the user to perform account sign up/log in and CRUD actions on todo items with Firebase. In this post, we are going to solely focus on the user signup and login part.

The Problem

Since Flutter web came out from beta this year, I've been wanting to make a full production app that works smoothly for both mobile, and web. This obviously meant integrating Firebase Authentication (auth), Firebase Cloud Firestore, etc on my web and mobile app.

Doing so on mobile and web are no problems at all since dedicated packages are available to use Firebase Authentication (auth) and Firebase Cloud Firestore on mobile and web separately.

Firebase libraries for mobile:

firebase_core

firebase_auth

could_firestore

Firebase libraries for web:

firebase

The real problems arise when you try to add both of these in the single codebase. Have a look at the problems I faced here and here.

The Solution

UPDATE 1: fb_auth package, as highlighted by jeremywhiteley, seems to do the job for authentication, without going through everything below. If your need is the only authentication, then this package is a better option.

UPDATE 2: The above solution does not work reliably, at least not for me. It also lacks many of the needed methods provided in the original plugin.

Add Dependencies

Starting with the dependencies, add the following to your pubspec.yaml and run “flutter pub get”.

flutter pub get, loading dependencies pubspec.yaml

Done? Awesome, you’re done with the first step!

Let’s continue with Firebase registration.

Firebase registration Android

If you’re unaware with the process of integrating firebase with your project, check out one of many Firebase login guides available. This article by David Cheah is very detailed and simple to follow.

Let me fast forward registering my test app in Firebase:

Add a new Firebase project
Enter your app name and continue

You can follow the steps here to get your debug SHA-1 signing key:

Add your package name, app name, and SHA-1
Place the google-services.json in the “project_name/android/app” directory

Click next, continue, and that’s it, the Android part is done! you can follow a similar process to add your iOS app.

Adding code for Firebase auth Firebase Cloud Firestore

First, go ahead and enable Authentication (Google sign-in in this case) and Firestore from Firebase console.

Firebase Authentication
Firebase Cloud Firestore

The Code (Firebase Authentication)

Let us now write the logic for Signing the user in with their Google accounts.

This function will be used to login for the first time:

To check if the user is logged in the next time the app is launched, simply use the objGoogleSignIn.isSignedIn() method and also check if mobAuth is not null. isSignedIn() method returns a future, so use await for Async:

if (mobAuth != null && (await objGoogleSignIn.isSignedIn())) {
//User is logged in, Initialise the firebaseUser object
firebaseUser = await mobAuth.currentUser();
}else{
//User is not logged in, take them to the signin Screen
}

I moved these functions to a new file- “auth.dart” and named the class “AuthService”. So now, these can be just by declaring an object of the AuthService Class.

Let us make a Login page now:

Sign-in screen

The Code (Firebase Firestore)

To get data from Firestore:

Map<String, dynamic> userProfile = new Map();
Future<bool> getData() async {
dbFirestore.collection("Master").document(firebaseUser.email).snapshots().listen((snapshot) {
if (snapshot.data != null) {
userProfile = snapshot.data;
return true;
}else{
return false;
}
});
}

Set data to Firestore:

Future<bool> setData() async {
dbFirestore.collection('Master')
.document(firebaseUser.email)
.setData(userProfile, merge: false)
.then((onValue) async {
return true;
});
}

For Homescreen, let us implement a simple listview with a FloatingActionButton, where data gets added to the map when the button is clicked, and get uploaded to the database.

Another raised button “Clear” clears it.

“Homescreen.dart” will look like:

Firebase registration for Flutter Web

If you haven’t read already, have a look at this awesome article on Using Firebase in Flutter Web by Fun with Flutter. It is very simple and highly descriptive. We will follow the same steps to add Firebase in our test project here.

Next, you’ll need to include the Firebase JavaScript libraries in your .html file. For a Flutter project, the default HTML file is located at web/index.html.

<script src=”https://www.gstatic.com/firebasejs/6.6.0/firebase-app.js"></script><script src=”https://www.gstatic.com/firebasejs/6.6.0/firebase-auth.js"></script>

Your versions may be different. You can find the latest versions on the Firebase website. Additionally, you need to import the Firebase libraries that you will be using — for example, Auth, Database, Firestore. For a full list see the Firebase website.

Import firebase as WebFirebase:

import 'package:firebase/firebase.dart' as WebFirebase;

And initialize your Firebase project in main.dart:

void main() {
initializeApp(
apiKey: “YourApiKey”,
authDomain: “YourAuthDomain”,
databaseURL: “YourDatabaseUrl”,
projectId: “YourProjectId”,
storageBucket: “YourStorageBucket”);
}

The updated auth.dart should look something like this:

Flutter web login using Firebase
Flutter Cloud Firestore using Firebase

You can try out the web app here: https://test-firebase-flutter-project.firebaseapp.com/web/#/

Finally!

Conclusion

It is certainly not easy to use both sets of libraries in the same code base, and it’s a very hacky way to conditionally manage different objects for Web and Mobile. It is certainly possible, but I would not recommend making production apps on Flutter with the same codebase anytime soon.

I’d hope that the flutter team combines these different dependencies, and makes them one since currently web dependencies are mostly wraps of their js counterparts.

Another frustrating fact is every time you compile for mobile, you’ll have to compile out the web dependencies, otherwise, you’ll be greeted with this error:

Compiler message:
/C:/Users/prahu/AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/firebase-7.0.0/lib/src/top_level.dart:1:8: Error: Not found: 'dart:html'
import 'dart:html';
^
/C:/Users/prahu/AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/firebase-7.0.0/lib/src/utils.dart:2:8: Error: Not found: 'dart:html'
import 'dart:html' show promiseToFuture;
^

Anyways, there is no roadmap of grouping these separate dependencies. Till then, this is the way to go.

Source Code

--

--

Praharsh Bhatt
Multiverse Software

I'm not an entrepreneur, nor a CEO. I'm a nerdy programmer who likes to have opinions on Twitter.