Integrating Firebase Auth and Google Sign-in in Flutter Web

I have a Flutter app that uses Firebase Auth with Google Sign-in. I use it in Android and Firebase fine. Today I wanted to run it on web as well. I set up the project to support web (see post).

Then I went to the Firebase Console to add the web project to my app. It gave me instructions to copy/paste into my index.html. Great.

I also went to https://pub.dev/packages/firebase_auth#web-integration.

Upon running, it threw an exception telling me that I should set a value for google-signin-client_id in a meta field. That's weird because the docs didn't mention that. I didn't even know what this ID might look like.

A web search got me to this Google developers page. It has a neat feature where if you click on it, it shows you a popup that lists your Cloud projects. I selected mine and it said I had no credential yet. It redirected me to the Cloud Console's credentials page.

I found the key that Firebase created for me when I created a web client for the same project, so I added the meta field. Time to run the project again.

Boom! Another error:

gapi.auth2.ExternallyVisibleError: Invalid cookiePolicy

And it's another GitHub issue: https://github.com/flutter/flutter/issues/49539.

It turns out, running the project by running flutter run -d chrome will open the page at an URL that looks like this: http://[::1]:12345/#/ where 12345 is a random port. The ticket explains you have to open it at localhost instead of [::1]. This is the first time that I see such a domain name. I'm not sure what it means. So I changed the url to http://localhost:12345/#/ and it loaded. However, upon clicking my Sign-in button, it throw this error:

cb=gapi.loaded_0:163 Uncaught Error: PlatformException(google_sign_in, idpiframe_initialization_failed, Not a valid origin for the client: http://localhost:8080 has not been whitelisted for client ID [redacted].apps.googleusercontent.com. Please go to https://console.developers.google.com/ and whitelist this origin for your project's client ID.)

Now I understand better the comment in the GitHub issue mentioned above, where ditman shows a command to run the project at a predefined port. So I used flutter run -d chrome --web-port 5000.

It took a few minutes to update. This time the Google sign-in popup opened and asked me for my email address. I put in my gmail address, and it sent me to https://accounts.google.com/signin/oauth/deniedsigninrejected, and said it could not sign me in safely. It also told me to try another browser. I was already on Chrome... This is the issue that another user reported in the same thread: https://github.com/flutter/flutter/issues/49539#issuecomment-580478849, but they didn't seem to file another ticket.

After looking some more, I this StackOverflow post. They say that if you run the same page on a non debugged instance of Chrome, it'll work without issue. Instead, I get this error when it loads:

Access to fetch at 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/getAccountInfo?key=...' from origin 'http://localhost:5000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'.

On the plus side, if I compile the application with flutter build web and run that, things work without any issue.