🥵
【firebase x flutter web】動的ルーティング時のtips
この記事でわかること
- firebase hostingでホスティングしているflutter webにおいて、動的ルーティングの実装後、アクセスすると
Cannot GET XXX/xxx
となる問題の解決策
発生した問題
前提条件
- flutter web(firebaseでホスティング)
- 利用パッケージ
- GoRouter: flutterにルーティングを実装するパッケージ
- ディレクトリ
- lib
- main.dart
- firebase.json
コード
main.dart
// flutter内蔵パッケージ
import 'package:flutter/material.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
import 'package:go_router/go_router.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_service/firebase_options.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
setUrlStrategy(PathUrlStrategy());
runApp(MainApp());
}
class MainApp extends StatefulWidget {
const MainApp({super.key});
Widget build(BuildContext context) {
final rootNavigatorKey = GlobalKey<NavigatorState>();
final homeNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'home');
final favorireNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'favorite');
final settingNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'account');
final router = GoRouter(
navigatorKey: rootNavigatorKey,
initialLocation: '/',
routes: [
StatefulShellRoute.indexedStack(
parentNavigatorKey: rootNavigatorKey,
builder: (context, state, navigationShell) =>
AppNavigationBar(navigationShell: navigationShell),
branches: [
// home
StatefulShellBranch(
navigatorKey: homeNavigatorKey,
routes: [
GoRoute(
path: '/',
builder: (context, state) =>
const Text('Home'),
routes: [
GoRoute(
path: 'example1/:name',
builder: (context, state) {
final String name = state.pathParameters['name']!;
return Text(name);
},
),
GoRoute(
path: 'example2/:name',
builder: (context, state) {
final String name = state.pathParameters['name']!;
return Text(name);
},
),
],
),
],
),
// favorite
StatefulShellBranch(
navigatorKey: favorireNavigatorKey,
routes: ...
),
// setting
StatefulShellBranch(
navigatorKey: settingNavigatorKey,
routes: ...
),
],
),
],
);
return MaterialApp.router(
title: 'sample',
routerConfig: router,
);
}
}
やったこと
-
{XXXXX}/example1/aaa
にアクセスする
期待した結果
- 画面上に
aaa
と表示される
実際の結果
-
Cannot GET /example1/aaa
と表示される
発生原因
- ルートディレクトリ直下の
firebase.json
の設定忘れ- ルート以外にアクセス(ここでは
/example1/aaa
)しても、aaa
というファイルは存在しないため、エラーが発生する
- ルート以外にアクセス(ここでは
解決策
- 全てのリクエストに対して、
index.html
を返すように、firebase.json
を書き換える
firebase.json
{
"hosting": {
"source": ".",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"frameworksBackend": {
"region": "asia-east1"
},
+ "rewrites": [
+ {
+ "source": "**",
+ "destination": "/index.html"
+ }
+ ]
},
...
}
参考文献
Discussion