You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中Go_Router+Firebase Hosting的DeepLink兼容问题求助

兼容GoRouter DeepLink与Firebase Hosting Web访问的解决方案

你的问题核心是带#的链接在APP里路由不匹配,去掉#后Web端Firebase返回404,下面分两步解决,确保两端都正常工作:

一、修复APP端带#的DeepLink路由问题

当APP收到带#的DeepLink时,GoRouter拿到的location是完整的scheme/host/#/firstScreen/...,但你的路由配置是基于/firstScreen/...的,所以得先把多余的前缀砍掉,只留#后面的路由部分。

两种处理方式:

1. 用GoRouter的redirect自动处理

初始化GoRouter时加个redirect逻辑,自动提取有效路由:

final router = GoRouter(
  initialLocation: '/',
  redirect: (context, state) {
    final rawLocation = state.location;
    // 检查是否包含#,拆分出后面的路由路径
    if (rawLocation.contains('#')) {
      final validRoute = rawLocation.split('#').last;
      // 如果拆分后是空的,跳首页,否则用提取出的路由
      return validRoute.isNotEmpty ? validRoute : '/';
    }
    return null; // 不需要重定向,用原路径
  },
  routes: [
    // 你的路由配置,比如:
    GoRoute(
      path: '/firstScreen',
      builder: (context, state) => const FirstScreen(),
      routes: [
        GoRoute(
          path: 'secondScreen',
          builder: (context, state) {
            final targetId = state.uri.queryParameters['id'];
            return SecondScreen(targetId: targetId);
          },
        ),
      ],
    ),
  ],
);

2. 在DeepLink监听里预处理(比如用app_links/firebase_dynamic_links)

如果你是通过第三方库监听DeepLink的,拿到链接后先解析再跳转:

// 以app_links为例
AppLinks().uriLinkStream.listen((Uri uri) {
  String targetRoute;
  if (uri.fragment.isNotEmpty) {
    // 带#的链接,取fragment部分
    targetRoute = uri.fragment;
  } else {
    // 不带#的链接,直接取path
    targetRoute = uri.path;
  }
  // 确保路由以/开头,避免错误
  if (!targetRoute.startsWith('/')) {
    targetRoute = '/$targetRoute';
  }
  router.go(targetRoute);
});

这样处理后,不管链接带不带#,APP都能正确匹配路由。

二、修复Firebase Hosting无#路径的404问题

用setPathUrlStrategy()去掉#后,Web端的路由是真实路径(比如/firstScreen/secondScreen),Firebase Hosting默认会去找这个路径下的静态文件,找不到就返回404。解决办法是配置重写规则,让所有请求都指向Flutter的index.html。

修改firebase.json

打开项目根目录的firebase.json,在hosting里加rewrites规则:

{
  "hosting": {
    "public": "build/web",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}

这个规则的意思是:所有请求路径(**匹配任意路径)都转到index.html,让Flutter单页应用自己处理路由,不会再出现404。

配置完重新部署:

firebase deploy --only hosting

三、最终兼容方案

  1. Web端保留PathUrlStrategy:用setPathUrlStrategy()去掉URL中的#,配合Firebase的重写规则解决404。
  2. APP端兼容两种链接格式:不管接收到的链接带不带#,都提取出正确的路由路径传给GoRouter。

这样就能同时满足:

  • 未装APP的设备点击链接,跳转到Web端对应页面(无#路径,正常访问)。
  • 已装APP的设备点击链接,APP启动后正确匹配路由。

内容的提问来源于stack exchange,提问作者foseja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 00:22:11