Flutter Web项目中Firebase JS SDK抛出未捕获语法错误求助
Flutter Web + Firebase 控制台语法错误排查
首次基于Flutter开发Firebase Web应用,浏览器控制台出现大量未捕获语法错误,需解决该问题以实现用户认证、登录及登出功能。
index.html 中的 Firebase SDK 引入代码
<!DOCTYPE html> <html> <head> <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="lithaexpress_admin_web_portal"> <link rel="apple-touch-icon" href="icons/Icon-192.png"> <!-- Favicon --> <link rel="icon" type="image/png" href="favicon.png"/> <title>lithaexpress_admin_web_portal</title> <link rel="manifest" href="manifest.json"> <script> // The value below is injected by flutter build, do not touch. const serviceWorkerVersion = null; </script> <!-- This script adds the flutter initialization JS code --> <script src="flutter.js" defer></script> </head> <body> <script> window.addEventListener('load', function(ev) { // Download main.dart.js _flutter.loader.loadEntrypoint({ serviceWorker: { serviceWorkerVersion: serviceWorkerVersion, }, onEntrypointLoaded: function(engineInitializer) { engineInitializer.initializeEngine().then(function(appRunner) { appRunner.runApp(); }); } }); }); </script> <script src="https://www.gstatic.com/firebasejs/10.3.1/firebase-app.js"></script> <script src="https://www.gstatic.com/firebasejs/10.3.1/firebase-auth.js"></script> <script src="https://www.gstatic.com/firebasejs/10.3.1/firebase-firestore.js"></script> <script src="main.dart.js" type="application/javascript"></script> <script src="https://www.gstatic.com/firebasejs/10.3.1/firebase-analytics.js"></script> <script> // Your web app's Firebase configuration const firebaseConfig = { #firebase config info }; // Initialize Firebase firebase.initializeApp(firebaseConfig); firebase.analytics(); </script> </body> </html>
登录页面代码(LoginScreen.dart)
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:mohaexpress_admin_web_portal/main_screens/home_screen.dart'; class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); @override State<LoginScreen> createState() => _LoginScreenState(); } class _LoginScreenState extends State<LoginScreen> { String adminEmail = ''; String adminPassword = ''; allowAdminToLogin() async { SnackBar snackBar = const SnackBar( content: Text( 'Checking Credentials, Please Wait... ', style: TextStyle( fontSize: 36, color: Colors.black, ), ), backgroundColor: Colors.pinkAccent, duration: Duration(seconds: 6), ); ScaffoldMessenger.of(context).showSnackBar(snackBar); User? currentAdmin; await FirebaseAuth.instance .signInWithEmailAndPassword( email: adminEmail, password: adminPassword, ) .then((fAuth) { currentAdmin = fAuth.user; }).catchError((onError) { final snackBar = SnackBar( content: Text( 'Error Occured: $onError', style: const TextStyle( fontSize: 36, color: Colors.black, ), ), backgroundColor: Colors.pinkAccent, duration: const Duration(seconds: 5), ); ScaffoldMessenger.of(context).showSnackBar(snackBar); }); if (currentAdmin != null) { await FirebaseFirestore.instance .collection('admins') .doc(currentAdmin!.uid) .get() .then((snap) { if (snap.exists) { Navigator.push( context, MaterialPageRoute( builder: (c) => const HomeScreen(), ), ); } else { SnackBar snackBar = const SnackBar( content: Text( 'No record found, you are not an admin.', style: TextStyle( fontSize: 36, color: Colors.black, ), ), backgroundColor: Colors.pinkAccent, duration: Duration(seconds: 6), ); ScaffoldMessenger.of(context).showSnackBar(snackBar); } }); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, body: Stack( children: [ Center( child: SizedBox( width: MediaQuery.of(context).size.width * 0.5, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( 'images/admin.png', ), TextField( onChanged: (value) { adminEmail = value; }, style: const TextStyle( fontSize: 16, color: Colors.white, ), decoration: const InputDecoration( enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: Colors.green, width: 2, ), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide( color: Colors.amber, width: 2, ), ), hintText: 'Email', hintStyle: TextStyle(color: Colors.grey), icon: Icon( Icons.email, color: Colors.green, ), ), ), const SizedBox( height: 20, ), TextField( onChanged: (value) { adminPassword = value; }, obscureText: true, style: const TextStyle( fontSize: 16, color: Colors.white, ), decoration: const InputDecoration( enabledBorder: OutlineInputBorder( borderSide: BorderSide( color: Colors.green, width: 2, ), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide( color: Colors.amber, width: 2, ), ), hintText: 'Password', hintStyle: TextStyle(color: Colors.grey), icon: Icon( Icons.admin_panel_settings, color: Colors.green, ), ), ), const SizedBox( height: 30, ), ElevatedButton( onPressed: () { allowAdminToLogin(); }, style: ButtonStyle( padding: MaterialStateProperty.all( const EdgeInsets.symmetric( horizontal: 90, vertical: 20), ), backgroundColor: MaterialStateProperty.all<Color>(Colors.green), foregroundColor: MaterialStateProperty.all<Color>(Colors.pinkAccent), ), child: const Text( 'Login', style: TextStyle( color: Colors.white, letterSpacing: 2, fontSize: 16, ), ), ), ], ), ), ), ], ), ); } }
main.dart 代码
import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:mohaexpress_admin_web_portal/authentication/login_screen.dart'; Future<void> main() async { await Firebase.initializeApp(); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'Admin Web Portal', theme: ThemeData( primarySwatch: Colors.green, ), debugShowCheckedModeBanner: false, home: const LoginScreen(), ); } }
错误原因及解决方案
核心问题分析
- 重复初始化Firebase:同时在
index.html的JS代码和Flutter的main.dart中初始化Firebase,导致冲突引发错误。 - 配置占位符语法错误:
index.html中firebaseConfig里的#firebase config info是无效JS语法,直接触发语法错误。 - 脚本加载逻辑错误:Flutter Web使用Firebase官方插件时,无需手动引入JS SDK,插件会自动处理依赖,手动引入会导致版本或初始化冲突。
具体修复步骤
移除index.html中的Firebase JS代码:
删除所有Firebase相关的<script>标签及初始化代码,包括SDK引入和firebase.initializeApp部分。添加Firebase配置文件:
在项目根目录创建firebase_options.dart,通过flutterfire configure命令生成(需先安装flutterfire_cli),或手动写入你的Firebase Web配置:import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/foundation.dart'; class DefaultFirebaseOptions { static FirebaseOptions get currentPlatform { if (kIsWeb) { return const FirebaseOptions( apiKey: "你的API_KEY", authDomain: "你的AUTH_DOMAIN", projectId: "你的PROJECT_ID", storageBucket: "你的STORAGE_BUCKET", messagingSenderId: "你的MESSAGING_SENDER_ID", appId: "你的APP_ID", measurementId: "你的MEASUREMENT_ID", ); } throw UnsupportedError('当前平台不支持默认Firebase配置'); } }修正main.dart初始化逻辑:
import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; import 'package:mohaexpress_admin_web_portal/authentication/login_screen.dart'; import 'firebase_options.dart'; Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); // 必须添加,确保Flutter绑定完成 await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'Admin Web Portal', theme: ThemeData( primarySwatch: Colors.green, ), debugShowCheckedModeBanner: false, home: const LoginScreen(), ); } }检查并更新依赖:
确保pubspec.yaml中依赖版本正确,执行flutter pub get更新:dependencies: flutter: sdk: flutter firebase_core: ^2.15.0 firebase_auth: ^4.10.0 cloud_firestore: ^4.8.0
额外注意事项
- Flutter Web项目中,优先使用Firebase官方Flutter插件,不要混用JS SDK,避免版本冲突。
- 确保Firebase控制台已正确创建Web应用,并复制完整的配置信息到
firebase_options.dart中。
内容的提问来源于stack exchange,提问作者Moha Nkossie
相关产品推荐
相关产品推荐

