我正在尝试将我的 Flutter 应用程序部署到 Firebase 托管。应用程序在 flutter run -d chrome 下运行良好,并使用 flutter build web --web-renderer html --release
成功构建在我的 flutter web 应用程序中,我有不止一页。我在用
速度_x:^3.3.0
用于页面路由,因为此插件使用 flutter 2.0 导航。
我在打开我的网络主页时遇到的问题在我通过单击打开的下一页转到另一个页面时工作正常但是当我刷新显示 404 not found 的第二页时我不明白我做错了什么.同样的事情在调试模式下运行良好,但在部署我的 flutter web 后,出现了 404 问题。 请帮助我,我尝试了很多但确实明白我应该做什么。
我的 main.dart 文件
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Hive.initFlutter();
Vx.setPathUrlStrategy();
Hive.registerAdapter(MultiAccountAdapter());
await Hive.openBox<MultiAccount>('accounts');
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
}
Locale locale;
void getPref() async {
var res = await SharedPref().getStringVariable("lan");
if (res != null) {
if (res != null && res == "ENGLISH") {
locale = Locale('en', 'US');
} else if (res != null && res == "DUTCH") {
locale = Locale('nl', 'NL');
} else {
locale = Locale('en', 'US');
}
} else {
locale = ui.window.locale;
// Get.updateLocale(locale);
}
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return OverlaySupport(
child: GetMaterialApp.router(
debugShowCheckedModeBanner: false,
translations: LocaleString(),
locale: locale,
theme: ThemeData(
primaryColor: green,
primaryColorDark: greenDark,
fontFamily: 'Montserrat-Medium',
accentColor: Colors.grey,
cursorColor: greenDark,
textTheme: TextTheme(
bodyText1: TextStyle(fontSize: 14.0),
),
),
routeInformationParser: VxInformationParser(),
routerDelegate: VxNavigator(
routes: VxRoutes.instance.newMethod,
),
),
);
}
}
我的路由文件
class VxRoutes {
static VxRoutes instance = VxRoutes();
Map<Pattern, VxPageBuilder> get newMethod {
return {
"/": (_, param) => VxRoutePage(
child: HomeScreen(
showSnackbar: param ?? false,
),
transition: (animation, child) => FadeTransition(
opacity: animation,
child: child,
),
),
SteplerDetailScreenRoute: (uri, params) {
var steplerId = uri.queryParameters["steplerId"];
if (steplerId == null || steplerId == "") {
return VxRoutePage(
child: CrashScreen(),
transition: (animation, child) => FadeTransition(
opacity: animation,
child: child,
),
);
}
return VxRoutePage(
child: SteplerDetailScreen(
steplerId: int.tryParse(steplerId.toString()),
),
transition: (animation, child) => FadeTransition(
opacity: animation,
child: child,
),
);
},
FullPhotoRoute: (uri, params) {
var url = uri.queryParameters["url"];
if (url == null || url == "") {
return VxRoutePage(
child: CrashScreen(),
transition: (animation, child) => FadeTransition(
opacity: animation,
child: child,
),
);
}
return VxRoutePage(
child: FullPhoto(
url: url,
),
transition: (animation, child) => FadeTransition(
opacity: animation,
child: child,
),
);
},
};
}
}
我的index.html
<!DOCTYPE html>
<html>
<head>
<base href="/">
<meta name="google-signin-client_id"abc">
<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="stepler_web">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png" />
<title>Stepler</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<script
async
defer
crossorigin="anonymous"
src="https://connect.facebook.net/en_US/sdk.js"
></script>
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-messaging.js"></script>
<script>
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "abc",
authDomain: "abc",
projectId: "abc",
storageBucket: "abc",
messagingSenderId: "abc",
appId: "abc",
measurementId: "abc"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
</script>
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('flutter-first-frame', function () {
navigator.serviceWorker.register('flutter_service_worker.js');
});
}
</script>
<script src="main.dart.js" type="application/javascript"></script>
</body>
</html>
按照这些步骤
转到您的 firebase 控制台(托管您的代码的地方)
编辑
.htaccess
(不存在请创建,有时不显示,所以启用显示隐藏文件)
编辑/添加给定代码。
RewriteEngine on
RewriteCond %{REQUEST_FILENAME}% !-d
RewriteCond %{REQUEST_FILENAME}% !-f
RewriteRule . /index.html [L]
这4行代码是做什么用的?
Ans:它重定向到
index.html
页面。
因为flutter web是一个单文件代码web应用,你的url是不存在的,比如你的url是
https://yourdomain.com/my-page
但是flutter web只有index.html
。所以我们强制将该 URL 重定向到 index.html
我通过删除这个
Vx.setPathUrlStrategy();
解决了这个问题
这里是另一种重写方式 在你的 firebase.json 文件中,添加这些行
// Serves index.html for requests to files or directories that do not exist
"rewrites": [ {
"source": "**",
"destination": "/index.html"
} ]
或完整代码
{
"hosting": {
"public": "...",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [ {
"source": "**",
"destination": "/index.html"
} ]
}
}
参考资料 https://firebase.google.com/docs/hosting/full-config?authuser=2