Golf
Golf

Reputation: 27

Firebase doesn't work on flutter web but fine on android emulator

I tried to use firebase auth on the app, it runs fine on android emu and able to create account and login but not on web(chrome). When I run the debug it gave an error of TypeError: Cannot read properties of undefined (reading 'app'). But if I run flutter build web --release and open the web link it returns ReferenceError: firebase is not defined. I have been google-ing for days, still unable to fix this issue. I'm at the dead-end not sure what to do. the const firebaseConfig = {...}; in the index.html was given from firebase auth when created an webapp project. Please help. not sure where it went wrong.

flutter doctor
[√] Flutter (Channel stable, 2.5.0, on Microsoft Windows [Version 10.0.22454.1000],locale   
    en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[√] Chrome - develop for the web
[√] Android Studio (version 2020.3)
[√] VS Code (version 1.60.2)
[√] Connected device (2 available)

flutter --version
Flutter 2.5.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 4cc385b4b8 (2 weeks ago) • 2021-09-07 23:01:49 -0700
Engine • revision f0826da7ef
Tools • Dart 2.14.0

in the pupspec.yaml

name: login_test
description: A new Flutter project.

publish_to: 'none'

version: 1.0.0+1

environment:
  sdk: ">=2.12.0 <3.0.0"

dependencies:
  cupertino_icons: ^1.0.2
  firebase_auth: ^3.1.1
  firebase_core: ^1.6.0
  flutter:
    sdk: flutter
  fluttertoast: ^8.0.8
  form_field_validator: ^1.1.0

dev_dependencies:
  flutter_lints: ^1.0.0
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true

in the web/index.html

<!DOCTYPE html>
<html>
<head>
  <!--
    If you are serving your web app in a path other than the root, change the
    href value below to reflect the base path you are serving from.

    The path provided below has to start and end with a slash "/" in order for
    it to work correctly.

    For more details:
    * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base

    This is a placeholder for base href that will be replaced by the value of
    the `--base-href` argument provided to `flutter build`.
  -->
  <base href="$FLUTTER_BASE_HREF">

  <meta charset="UTF-8">
  <meta content="IE=Edge" http-equiv="X-UA-Compatible">
  <meta name="description" content="A new Flutter project.">

  <!-- iOS meta tags & icons -->
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <meta name="apple-mobile-web-app-title" content="login_test">
  <link rel="apple-touch-icon" href="icons/Icon-192.png">

  <title>login_test</title>
  <link rel="manifest" href="manifest.json">
</head>
<body>
  <!-- Firebase Configuration -->
  <script type="module">
    // Import the functions you need from the SDKs you need
    import { initializeApp } from "https://www.gstatic.com/firebasejs/9.0.2/firebase-app.js";
    // TODO: Add SDKs for Firebase products that you want to use
    // https://firebase.google.com/docs/web/setup#available-libraries
    import { auth } from "https://www.gstatic.com/firebasejs/9.0.2/firebase-auth.js"
  
    // Your web app's Firebase configuration
    const firebaseConfig = {
      apiKey: "_________-_________",
      authDomain: "_________-_________.firebaseapp.com",
      projectId: "_________-_________",
      storageBucket: "_________-_________.appspot.com",
      messagingSenderId: "_________",
      appId: "1:_________:web:_________"
    };
  
    // Initialize Firebase
    const app = initializeApp(firebaseConfig);
  </script>
  <!-- This script installs service_worker.js to provide PWA functionality to
       application. For more information, see:
       https://developers.google.com/web/fundamentals/primers/service-workers -->
  <script>
    var serviceWorkerVersion = null;
    var scriptLoaded = false;
    function loadMainDartJs() {
      if (scriptLoaded) {
        return;
      }
      scriptLoaded = true;
      var scriptTag = document.createElement('script');
      scriptTag.src = 'main.dart.js';
      scriptTag.type = 'application/javascript';
      document.body.append(scriptTag);
    }

    if ('serviceWorker' in navigator) {
      // Service workers are supported. Use them.
      window.addEventListener('load', function () {
        // Wait for registration to finish before dropping the <script> tag.
        // Otherwise, the browser will load the script multiple times,
        // potentially different versions.
        var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;
        navigator.serviceWorker.register(serviceWorkerUrl)
          .then((reg) => {
            function waitForActivation(serviceWorker) {
              serviceWorker.addEventListener('statechange', () => {
                if (serviceWorker.state == 'activated') {
                  console.log('Installed new service worker.');
                  loadMainDartJs();
                }
              });
            }
            if (!reg.active && (reg.installing || reg.waiting)) {
              // No active web worker and we have installed or are installing
              // one for the first time. Simply wait for it to activate.
              waitForActivation(reg.installing || reg.waiting);
            } else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {
              // When the app updates the serviceWorkerVersion changes, so we
              // need to ask the service worker to update.
              console.log('New service worker available.');
              reg.update();
              waitForActivation(reg.installing);
            } else {
              // Existing service worker is still good.
              console.log('Loading app from service worker.');
              loadMainDartJs();
            }
          });

        // If service worker doesn't succeed in a reasonable amount of time,
        // fallback to plaint <script> tag.
        setTimeout(() => {
          if (!scriptLoaded) {
            console.warn(
              'Failed to load app from service worker. Falling back to plain <script> tag.',
            );
            loadMainDartJs();
          }
        }, 4000);
      });
    } else {
      // Service workers not supported. Just drop the <script> tag.
      loadMainDartJs();
    }
  </script>
  <script src="main.dart.js" type="application/javascript"></script>
</body>
</html>

Upvotes: 1

Views: 4001

Answers (2)

Rhuan Barros
Rhuan Barros

Reputation: 330

I think that I got what's happening. The problem is to integrate Flutter compiled to web with Firebase web api. The FlutterFire (it is the Flutter library to integrate with Firebase) was developed to integrate with the Firebase web api version 8.6.1. On the other hand, Firebase web api is already in version 9.x, and it has different method calls on initialization. So, the solution is to use Flutter web api 8.6.1 instead of 9.x like de Flutter web api documentation.

The confusion comes from when a beginner create a new Firebase app at the console and the page gives a code to put on the flutter web index.html, but in this case the code use Firebase web api 9.x version style.

TL;DR;

The code in the Flutter web/index.html needs to be exactly like this. Put in the beginning of the body tag. Just replace your firebaseConfig object.

<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-app.js"></script>
<script>
    var firebaseConfig = {
      apiKey: "----",
      authDomain: "----",
      projectId: "----",
      storageBucket: "----",
      messagingSenderId: "----",
      appId: "----"
    };
    firebase.initializeApp(firebaseConfig);
</script>

Use this libraries but replace the version to 8.6.1.

Upvotes: 1

Gazihan Alankus
Gazihan Alankus

Reputation: 11984

You should really follow the official docs. If you follow it from the start carefully it will take you there. You'll occasionally see web-specific stuff like this:

https://firebase.flutter.dev/docs/installation/web https://firebase.flutter.dev/docs/firestore/overview#3-web-only-add-the-sdk

We use it in Flutter Web just fine using these instructions. Your index.html looks different from what's there in the docs. You probably followed a tutorial somewhere that is probably outdated now.

Upvotes: 0

Related Questions