How to migrate Flutter project to Firebase version-9 modern web modular style
Solution 1
Your flutter code does not follow what the docs suggest, especially where and how Firebase.initializeApp();
is called.
Here's a snippet directly from the docs:
import 'package:flutter/material.dart';
// Import the firebase_core plugin
import 'package:firebase_core/firebase_core.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(App());
}
/// We are using a StatefulWidget such that we only create the [Future] once,
/// no matter how many times our widget rebuild.
/// If we used a [StatelessWidget], in the event where [App] is rebuilt, that
/// would re-initialize FlutterFire and make our application re-enter loading state,
/// which is undesired.
class App extends StatefulWidget {
// Create the initialization Future outside of `build`:
@override
_AppState createState() => _AppState();
}
class _AppState extends State<App> {
/// The future is part of the state of our widget. We should not call `initializeApp`
/// directly inside [build].
final Future<FirebaseApp> _initialization = Firebase.initializeApp();
@override
Widget build(BuildContext context) {
return FutureBuilder(
// Initialize FlutterFire:
future: _initialization,
builder: (context, snapshot) {
// Check for errors
if (snapshot.hasError) {
return SomethingWentWrong();
}
// Once complete, show your application
if (snapshot.connectionState == ConnectionState.done) {
return MyAwesomeApp();
}
// Otherwise, show something whilst waiting for initialization to complete
return Loading();
},
);
}
}
As you can see, that function is called after runApp(App());
has been called.
Not only does Firebase.initializeApp();
return a Future<FirebaseApp>
(which you do not await
in your code), it is part of the main widget's state.
Solution 2
The Flutter Web bindings for Firebase are built on top of the pre-v9 API. As far as I can see in the Github repo, no discussion has been started on porting them to v9 yet. I'd recommend leaving it to the library's authors to decide when the best time is to migrate to the v9 modular API style, and use v8 until then as shown in the FlutterFire documentation on adding the Firebase SDKs to your web app.
If you insist on migrating to v9 already, you can use its -compat
builds, which bolts the previous API style on the new modular version. This will allow you to work with the latest builds, although it will not give you the (full) size benefits of the new modular API.
Mithson
Computer Science Enthusiast learning to be good at problem solving Interested in creation of mobile application, web app, desktop apps and embedded systems. Skilled in logic, Algebra and Discrete maths. I am well versed in Python, C, SQL, Javascript, Flutter, Java, Angular, HTML, CSS, Linux, Algorithms and Data structure Handy with softwares like netbeans, Android studio, vscode and Visual studio.
Updated on January 01, 2023Comments
-
Mithson over 1 year
I am facing problem with initializing the Firebase and Flutter project, while I just updated my
firebase-tools
andfirebase
to version 9 which is modern web modular style and its been a week nothing has helped the documentation of flutter is still according to version 8 which is old style compat type and when I follow firebase documentation which is updated its throwing errors with flutter. I need your help firebase and flutter experts please provide some solution.The two error which I get are,
core.dart:56 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'app') at Object.app$ [as app] (core.dart:56) at initializeApp (firebase_core_web.dart:68) at initializeApp.next (<anonymous>) at runBody (async_patch.dart:84) at Object._async [as async] (async_patch.dart:123) at firebase_core_web.FirebaseCoreWeb.new.initializeApp (firebase_core_web.dart:28) at initializeApp (firebase.dart:42) at initializeApp.next (<anonymous>) at runBody (async_patch.dart:84) at Object._async [as async] (async_patch.dart:123) at Function.initializeApp (firebase.dart:38) at main$ (main.dart:9) at main$.next (<anonymous>) at runBody (async_patch.dart:84) at Object._async [as async] (async_patch.dart:123) at main$ (main.dart:7) at main (web_entrypoint.dart:19) at main.next (<anonymous>) at async_patch.dart:45 at _RootZone.runUnary (zone.dart:1613) at _FutureListener.thenAwait.handleValue (future_impl.dart:155) at handleValueCallback (future_impl.dart:707) at Function._propagateToListeners (future_impl.dart:736) at _Future.new.[_completeWithValue] (future_impl.dart:542) at future.dart:401 at _RootZone.runUnary (zone.dart:1613) at _FutureListener.then.handleValue (future_impl.dart:155) at handleValueCallback (future_impl.dart:707) at Function._propagateToListeners (future_impl.dart:736) at _Future.new.[_completeWithValue] (future_impl.dart:542) at async._AsyncCallbackEntry.new.callback (future_impl.dart:580) at Object._microtaskLoop (schedule_microtask.dart:40) at _startMicrotaskLoop (schedule_microtask.dart:49) at async_patch.dart:166
and
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ js_primitives.dart:30 The following JSNoSuchMethodError was thrown building MyApp(dirty): js_primitives.dart:30 TypeError: Cannot read properties of undefined (reading 'app') js_primitives.dart:30 js_primitives.dart:30 The relevant error-causing widget was: js_primitives.dart:30 MyApp file:///C:/Users/Neha/AndroidStudioProjects/devcom/lib/main.dart:10:10 js_primitives.dart:30 js_primitives.dart:30 When the exception was thrown, this was the stack: js_primitives.dart:30 C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 236:49 throw_ js_primitives.dart:30 packages/firebase_core_web/firebase_core_web.dart 73:3 _catchJSError js_primitives.dart:30 packages/firebase_core_web/src/firebase_core_web.dart 138:13 app js_primitives.dart:30 packages/firebase_core/src/firebase.dart 55:41 app js_primitives.dart:30 packages/firebase_auth/src/firebase_auth.dart 38:47 get instance js_primitives.dart:30 packages/devcom/auth.dart 12:51 new js_primitives.dart:30 packages/devcom/main.dart 17:13 build js_primitives.dart:30 packages/flutter/src/widgets/framework.dart 4648:28 build js_primitives.dart:30 packages/flutter/src/widgets/framework.dart 4574:15 performRebuild js_primitives.dart:30 packages/flutter/src/widgets/framework.dart 4267:5 rebuild js_primitives.dart:30 packages/flutter/src/widgets/framework.dart 4553:5 [_firstBuild] js_primitives.dart:30 packages/flutter/src/widgets/framework.dart 4548:5 mount js_primitives.dart:30 packages/flutter/src/widgets/framework.dart 3611:13 inflateWidget js_primitives.dart:30 packages/flutter/src/widgets/framework.dart 3363:18 updateChild js_primitives.dart:30 packages/flutter/src/widgets/binding.dart 1189:16 [_rebuild] js_primitives.dart:30 packages/flutter/src/widgets/binding.dart 1159:5 mount js_primitives.dart:30 packages/flutter/src/widgets/binding.dart 1104:16 <fn> js_primitives.dart:30 packages/flutter/src/widgets/framework.dart 2535:19 buildScope js_primitives.dart:30 packages/flutter/src/widgets/binding.dart 1103:12 attachToRenderTree js_primitives.dart:30 packages/flutter/src/widgets/binding.dart 936:24 attachRootWidget js_primitives.dart:30 packages/flutter/src/widgets/binding.dart 917:7 <fn> js_primitives.dart:30 C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/isolate_helper.dart 48:19 internalCallback js_primitives.dart:30 js_primitives.dart:30 ════════════════════════════════════════════════════════════════════════════════════════════════════
main.dart
:import 'package:flutter/material.dart'; import 'package:devcom/auth.dart'; import 'package:devcom/auth_provider.dart'; import 'package:devcom/root_page.dart'; import 'package:firebase_core/firebase_core.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); Firebase.initializeApp(); runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return AuthProvider( auth: Auth(), child: MaterialApp( title: 'Flutter login demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: RootPage(), ), ); } }
index.html
:<!DOCTYPE html> <html> <head> <!-- <script src="https://www.gstatic.com/firebasejs/9.0.1/firebase-app.js" type = "module"></script> <script src="https://www.gstatic.com/firebasejs/9.0.1/firebase-analytics.js" type = "module"> </script> <script src="https://www.gstatic.com/firebasejs/9.0.1/firebase-auth.js" type = "module"></script> --> <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="devcom"> <link rel="apple-touch-icon" href="icons/Icon-192.png"> <!-- Favicon --> <link rel="shortcut icon" type="image/png" href="favicon.png" /> <title>Devcom</title> <link rel="manifest" href="manifest.json"> </head> <body > <!-- The core Firebase JS SDK is always required and must be listed first --> <script type="module"> import { initializeApp } from 'https://www.gstatic.com/firebasejs/9.0.1/firebase-app.js'; import { } from 'https://www.gstatic.com/firebasejs/9.0.1/firebase-auth.js'; import { getAnalytics } from "https://www.gstatic.com/firebasejs/9.0.1/firebase-analytics.js"; const firebaseConfig = { apiKey: "...", authDomain: "......", databaseURL: ".....", projectId: "...", storageBucket: "", messagingSenderId: "", measurementId: "", appId: "1:.........:web:...........", }; const app = initializeApp({ firebaseConfig }); // const app = getAnalytics({ firebaseConfig }) </script> <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> </body> </html>
-
Mithson over 2 yearsI am new to firebase, so how can I downgrade my firebase version to the version which flutter supports which is currently I guess 8.6.1 or use comat version-9 of firebase with flutter
-
Mithson over 2 yearsdoes uninstalling the Firebase with npm and installing again insures that it will be compatible version with Flutter or we need to specify it
-
Frank van Puffelen over 2 yearsThe documentation I linked shows exactly what to add, which is indeed version 8.6.1, like
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-app.js"></script>
. Once you do that, you can also use the code snippet to initialize Firebase that is shown on that page. -
Mithson over 2 yearsI did what you suggested now every errors are gone but the now its executing the first
if statement
with conditionsnapshot.hasError
and returningSomethingWentWrong()
code -
Mithson over 2 yearsthanks man Its working now problem cause was 'auth' in
main.dart