Firebase in Flutter Web

Firebase recently added Flutter Web support for Firestore, Firebase Auth and Firestore Storage. Here's how I set up a pre-existing Flutter + Firestore mobile app to run on Web.

Feb 2022 update

The latest doc to set it up is at https://firebase.google.com/docs/flutter/setup?platform=web. Now we don't need to modify index.html with custom js imports anymore!

Set up the Web project

First I ran flutter create . as instructed at https://flutter.dev/docs/get-started/web#add-web-support-to-an-existing-app.

Add js libs to index.html

I went over to https://pub.dev/packages/cloud_firestore to get the set up instructions. They redirect us to https://firebase.flutter.dev/docs/firestore/usage/. At the footer of the page, they have a page dedicated to Web: https://firebase.flutter.dev/docs/installation/web. This page shows how to add the dependency to firebase-app.js, and initialize the project.

Heading over to Firebase Console, I added a Web app to my app.

Adding the web app in Firestore Console

The odd thing is when I added the web app in Firestore Console, instead of showing me the JS code snippet to initialize the app, it showed me this snippet:

<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="/__/firebase/8.3.1/firebase-app.js"></script>

<!-- TODO: Add SDKs for Firebase products that you want to use
     https://firebase.google.com/docs/web/setup#available-libraries -->

<!-- Initialize Firebase -->
<script src="/__/firebase/init.js"></script>

It's only after I got out of the "create web app" wizard, and went into Project settings, apps, web, that I got the choice of Firebase SDK snippet between automatic, CDN (script imports and the initialization code) and Config (just the initialization variable definition).

CDN is the one I want.

Setting up Google Sign-in

After setting things up, it was time to try running it. I used flutter run -d chrome as mentioned at https://flutter.dev/docs/get-started/web#command-line. When I ran it, I got an error telling me the project's client ID wasn't set up. To find it, go to your Firebase Console, Authentication, Methods, click Google, then expand Web SDK configuration.

After adding the meta tag to my index.html, then running the project again, I got this error in the Chrome debugger tools:

Caught error: PlatformException(idpiframe_initialization_failed, Not a valid origin for the client: localhost:53677 has not been registered for client ID [redacted].apps.googleusercontent.com. Please go to https://console.developers.google.com/ and register this origin for your project's client ID., https://developers.google.com/identity/sign-in/web/reference#error_codes, null)

If you go to console.developers.google.com, you'll see that localhost:5000 is white-listed, but not the random port that flutter run -d chrome uses. So instead, we should specify the port web running that command:

flutter run -d chrome --web-port 5000

Once it ran on the right port, sign in with Google worked fine.

Firebase hosting

To set up Firebase hosting, I used https://firebase.google.com/docs/hosting/quickstart. First sign in with firebase login, then firebase init hosting. I set up the path to deploy as build/web, since this is where flutter build web outputs the build.

Finally I deployed by running. It output a link for me to check out my app: https://[redacted].web.app/. When I tried to sign in, it failed, telling me it wasn't whitelisted in Google Sign in.

It turns out, Firestore whitelists automatically the domain https://[redacted].firebaseapp.com/ in the Cloud Console, but not .web.app. I had to add that manually in the Cloud Console Credentials, Web client (auto created by Google Service), Authorized JavaScript origins. After clicking Save, it took a few minutes to propagate.