Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 [web] Modularly importing v9 Firebase JS SDK doesn't work #6967

Closed
yuxcat opened this issue Sep 8, 2021 · 3 comments
Closed

🐛 [web] Modularly importing v9 Firebase JS SDK doesn't work #6967

yuxcat opened this issue Sep 8, 2021 · 3 comments
Labels
platform: web Issues / PRs which are specifically for web. plugin: core type: bug Something isn't working

Comments

@yuxcat
Copy link

yuxcat commented Sep 8, 2021

Bug report

Describe the bug

When using Cloud_Firestore along with WEB Modular version 9 SDK, it throws bunch of errors.
also while in debug, IDE also point towards to "web_entrypoint.dart" file's Future main function.

Error :

Click to Expand the Error
core.dart:56 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'app')
    at Object.app$ [as app] (core.dart:56)
    at new cloud_firestore_web.FirebaseFirestoreWeb.new (cloud_firestore_web.dart:40)
    at Function.registerWith (cloud_firestore_web.dart:33)
    at Object.registerPlugins (generated_plugin_registrant.dart:15)
    at main (web_entrypoint.dart:14)
    at main.next (<anonymous>)
    at runBody (async_patch.dart:84)
    at Object._async [as async] (async_patch.dart:123)
    at main$ (web_entrypoint.dart:13)
    at main_module.bootstrap.js:19
    at Array.forEach (<anonymous>)
    at window.$dartRunMain (main_module.bootstrap.js:18)
    at <anonymous>:1:8
    at Object.runMain (client.js:8452)
    at client.js:24130
    at _wrapJsFunctionForAsync_closure.$protected (client.js:4461)
    at _wrapJsFunctionForAsync_closure.call$2 (client.js:11511)
    at Object._asyncStartSync (client.js:4425)
    at main__closure3.$call$body$main__closure (client.js:24142)
    at main__closure3.call$1 (client.js:24069)
    at StaticClosure._rootRunUnary (client.js:4823)
    at _CustomZone.runUnary$2$2 (client.js:12879)
    at _CustomZone.runUnaryGuarded$1$2 (client.js:12826)
    at _ForwardingStreamSubscription._sendData$1 (client.js:12416)
    at _ForwardingStreamSubscription._add$1 (client.js:12362)
    at _ForwardingStreamSubscription._add$1 (client.js:12695)
    at _MapStream._handleData$2 (client.js:12756)
    at _ForwardingStreamSubscription._handleData$1 (client.js:12721)
    at Object.eval (eval at Closure_forwardCallTo (client.js:1701), <anonymous>:3:44)
    at StaticClosure._rootRunUnary (client.js:4823)
    at _CustomZone.runUnary$2$2 (client.js:12879)
    at _CustomZone.runUnaryGuarded$1$2 (client.js:12826)
    at _ControllerSubscription._sendData$1 (client.js:12416)
    at _ControllerSubscription._add$1 (client.js:12362)
    at _SyncStreamController._sendData$1 (client.js:12201)
    at _SyncStreamController.add$1 (client.js:12082)
    at Object.eval (eval at Closure_forwardInterceptedCallTo (client.js:1781), <anonymous>:3:45)
    at StaticClosure._rootRunUnary (client.js:4823)
    at _CustomZone.runUnary$2$2 (client.js:12879)
    at _CustomZone.runUnaryGuarded$1$2 (client.js:12826)
    at _ControllerSubscription._sendData$1 (client.js:12416)
    at _ControllerSubscription._add$1 (client.js:12362)
    at _SyncStreamController._sendData$1 (client.js:12201)
    at _SyncStreamController.add$1 (client.js:12082)
    at _GuaranteeSink.add$1 (client.js:23581)
    at HtmlWebSocketChannel_closure1.call$1 (client.js:23874)
    at _EventStreamSubscription_closure.call$1 (client.js:18042)
    at StaticClosure._rootRunUnary (client.js:4829)
    at _CustomZone.runUnary$2$2 (client.js:12879)
    at _CustomZone.runUnaryGuarded$1$2 (client.js:12826)
    at _CustomZone_bindUnaryCallbackGuarded_closure.call$1 (client.js:13016)
    at invokeClosure (client.js:1524)
    at WebSocket.<anonymous> (client.js:1543)

Steps to reproduce

Steps to reproduce the behavior:

  1. use the sample provided by FlutterFire Docs or 2nd minimal sample below
  2. add Dependencies : firebase_core & cloud_firestore
  3. add Web Modular 9 SDK Config into web/index.html : CDN, SDK Setup and Configs of Project Settings
Click To Expand v9 Modular Config
<script type="module">

  // Import the functions you need from the SDKs you need

  import { initializeApp } from "https://www.gstatic.com/firebasejs/9.0.1/firebase-app.js";

  import { getAnalytics } from "https://www.gstatic.com/firebasejs/9.0.1/firebase-analytics.js";

  // TODO: Add SDKs for Firebase products that you want to use

  // https://firebase.google.com/docs/web/setup#available-libraries


  // Your web app's Firebase configuration

  // For Firebase JS SDK v7.20.0 and later, measurementId is optional

  const firebaseConfig = {

    apiKey: "API_KEY",

    authDomain: "PROJECT_ID.firebaseapp.com",

    projectId: "PROJECT_ID",

    storageBucket: "PROJECT_ID.appspot.com",

    messagingSenderId: "SENDER_ID",

    appId: "APP_ID",

    measurementId: "G-MEASUREMENT_ID"

  };


  // Initialize Firebase

  const app = initializeApp(firebaseConfig);

  const analytics = getAnalytics(app);

</script>


Expected behavior

since Flutter Web working fine with WEB v9 Modular SDK, i expected to work fine with cloud_firestore.

Sample project

Click To Expand Main.dart
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(App());
}

class App extends StatefulWidget {
  _AppState createState() => _AppState();
}

class _AppState extends State<App> {
  bool _initialized = false;
  bool _error = false;

  void initializeFlutterFire() async {
    try {
      await Firebase.initializeApp();
      setState(() {
        _initialized = true;
      });
    } catch (e) {
      setState(() {
        _error = true;
      });
    }
  }

  @override
  void initState() {
    initializeFlutterFire();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    if (_error) {
      return const Text("Error");
    }

    if (!_initialized) {
      return const Text("Loading");
    }

    return const Scaffold(
        body: Center(
      child: Text("Modular 9 fast boi"),
    ));
  }
}

Click To Expand 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="test1">
  <link rel="apple-touch-icon" href="icons/Icon-192.png">

  <!-- Favicon -->
  <link rel="icon" type="image/png" href="favicon.png"/>

  <title>test1</title>
  <link rel="manifest" href="manifest.json">
</head>
<body>
  <!-- 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 type="module">

    // Import the functions you need from the SDKs you need
  
    import { initializeApp } from "https://www.gstatic.com/firebasejs/9.0.1/firebase-app.js";
  
    import { getAnalytics } from "https://www.gstatic.com/firebasejs/9.0.1/firebase-analytics.js";

    import { getFirestore } from "https://www.gstatic.com/firebasejs/9.0.1/firebase-firestore.js";
  
    // TODO: Add SDKs for Firebase products that you want to use
  
    // https://firebase.google.com/docs/web/setup#available-libraries
  
  
    // Your web app's Firebase configuration
  
    // For Firebase JS SDK v7.20.0 and later, measurementId is optional
  
    const firebaseConfig = {
  
      apiKey: "API_KEY",
  
      authDomain: "PROJECT_ID.firebaseapp.com",
  
      projectId: "PROJECT_ID",
  
      storageBucket: "PROJECT_ID.appspot.com",
  
      messagingSenderId: "SENDER_ID",
  
      appId: "APP_ID",
  
      measurementId: "G-MEASUREMENT_ID"
  
    };
  
  
    // Initialize Firebase
  
    const app = initializeApp(firebaseConfig);
  
    const analytics = getAnalytics(app);
  
  </script>
</body>
</html>

Minimal Sample 2 :

Click To Expand Example 2 main.dart 👈
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Welcome to Flutter'),
        ),
        body: const Center(
          child: Text('web v9 nice'),
        ),
      ),
    );
  }
}


use the same index.html above

Additional context

this issue could fix in 2 options

  1. by Downgrading to Web SDK v8 / Config
  2. Removing Cloud_Firestore dependency

i'm looking for a solution to get flutter WEB along with v9 modular SDK to work with firestore because flutter web v9 significantly faster than version 8 WEB SDK.

plzz thank you 😥


Flutter doctor

Run flutter doctor and paste the output below:

Click To Expand
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.5.0, on Debian GNU/Linux 11 (bullseye) 5.10.0-8-amd64, locale en_US.UTF-8)
[✓] 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.0)
[✓] Connected device (1 available)

• No issues found!

Flutter dependencies

Click To Expand
Dart SDK 2.14.0
Flutter SDK 2.5.0
test1 1.0.0+1

dependencies:
- cloud_firestore 2.5.1 [cloud_firestore_platform_interface cloud_firestore_web collection firebase_core firebase_core_platform_interface flutter meta]
- cupertino_icons 1.0.3
- firebase_core 1.6.0 [firebase_core_platform_interface firebase_core_web flutter meta]
- flutter 0.0.0 [characters collection meta typed_data vector_math sky_engine]

dev dependencies:
- flutter_lints 1.0.4 [lints]
- flutter_test 0.0.0 [flutter test_api path fake_async clock stack_trace vector_math async boolean_selector characters charcode collection matcher meta source_span stream_channel string_scanner term_glyph typed_data]

transitive dependencies:
- async 2.8.1 [collection meta]
- boolean_selector 2.1.0 [source_span string_scanner]
- characters 1.1.0
- charcode 1.3.1
- clock 1.1.0
- cloud_firestore_platform_interface 5.4.1 [collection firebase_core flutter meta plugin_platform_interface]
- cloud_firestore_web 2.4.1 [cloud_firestore_platform_interface collection firebase_core firebase_core_web flutter flutter_web_plugins js]
- collection 1.15.0
- fake_async 1.2.0 [clock collection]
- firebase_core_platform_interface 4.0.1 [collection flutter meta plugin_platform_interface]
- firebase_core_web 1.1.0 [firebase_core_platform_interface flutter flutter_web_plugins js meta]
- flutter_web_plugins 0.0.0 [flutter js characters collection meta typed_data vector_math]
- js 0.6.3
- lints 1.0.1
- matcher 0.12.10 [stack_trace]
- meta 1.7.0
- path 1.8.0
- plugin_platform_interface 2.0.1 [meta]
- sky_engine 0.0.99
- source_span 1.8.1 [collection path term_glyph]
- stack_trace 1.10.0 [path]
- stream_channel 2.1.0 [async]
- string_scanner 1.1.0 [charcode source_span]
- term_glyph 1.2.0
- test_api 0.4.2 [async boolean_selector collection meta source_span stack_trace stream_channel string_scanner term_glyph matcher]
- typed_data 1.3.0 [collection]
- vector_math 2.1.0

@yuxcat yuxcat added Needs Attention This issue needs maintainer attention. type: bug Something isn't working labels Sep 8, 2021
@markusaksli-nc markusaksli-nc added the triage Issue is currently being triaged. label Sep 9, 2021
@markusaksli-nc
Copy link
Contributor

Well, the reason this happens is just that our current implementation relies on having the entire CDN, not importing it modularly. You can't be sure what you need to import and how for the dart channels to work properly. You for example aren't importing anything from https://www.gstatic.com/firebasejs/9.0.1/firebase-firestore.js so it's no wonder it doesn't work.

Not saying you did anything wrong, we just don't support this version yet.

I would close this since the current documentation works with the 8.6.1 version we test against but then again this will be an issue should we move to v9.

@markusaksli-nc markusaksli-nc added platform: web Issues / PRs which are specifically for web. plugin: core and removed Needs Attention This issue needs maintainer attention. triage Issue is currently being triaged. labels Sep 9, 2021
@markusaksli-nc markusaksli-nc changed the title 🐛 [WEB][Cloud_Firestore][V9] Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'app') 🐛 [web] Modularly importing v9 Firebase JS SDK doesn't work Sep 9, 2021
@Ehesp
Copy link
Member

Ehesp commented Sep 23, 2021

You can switch to the v9 compat versions (see #7041 (comment)) however they are currently untested against FlutterFire until that issue is closed.

Note; the compat versions will only bring bug fixes which landed in v9 SDKs. You won't see any bundle size improvements since there is no tree shaking.

@russellwheatley
Copy link
Member

Closing in favour of using this issue to track: #7041

@firebase firebase locked and limited conversation to collaborators Jan 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
platform: web Issues / PRs which are specifically for web. plugin: core type: bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants