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

如何用Flutter结合Firebase动态链接创建FireStore文章分享跳转链接

Flutter + Firebase 实现文章分享跳转功能

一、配置App深度链接(核心基础)

不管用自定义Scheme还是Firebase动态链接,都得先给App配置链接跳转支持:

Android 配置(AndroidManifest.xml)

在<activity>标签内添加intent-filter,支持自定义Scheme和HTTPS链接:

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <!-- 自定义Scheme,比如 myblog://article/xxx -->
    <data android:scheme="myblog" />
    <!-- 如果用Firebase动态链接的HTTPS域名,添加这个 -->
    <data android:host="your-dynamic-link-domain.page.link" android:scheme="https" />
</intent-filter>

iOS 配置(Info.plist)

添加URL Types和相关权限:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>myblog</string> <!-- 自定义Scheme -->
        </array>
    </dict>
</array>
<!-- 支持Universal Links(如果用HTTPS动态链接) -->
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <false/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>your-dynamic-link-domain.page.link</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <false/>
        </dict>
    </dict>
</dict>

二、生成文章分享链接

推荐用Firebase Dynamic Links,它能自动处理「用户未安装App时跳转到应用商店,已安装则直接打开App」的场景,比纯自定义Scheme更友好。

1. 依赖包

在pubspec.yaml添加:

firebase_dynamic_links: ^5.3.0

2. 生成动态链接代码

根据Firestore中文章的唯一ID生成链接:

import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';

Future<String> generateArticleShareLink(String articleId) async {
  final dynamicLinkParams = DynamicLinkParameters(
    link: Uri.parse('https://your-app-domain.com/article/$articleId'), // 备用链接(未安装App时跳转)
    uriPrefix: 'https://your-dynamic-link-domain.page.link', // Firebase控制台配置的动态链接前缀
    androidParameters: const AndroidParameters(
      packageName: 'com.your.app.package',
      minimumVersion: 1,
    ),
    iosParameters: const IOSParameters(
      bundleId: 'com.your.app.bundle',
      minimumVersion: '1.0',
    ),
  );

  final dynamicLink = await FirebaseDynamicLinks.instance.buildShortLink(dynamicLinkParams);
  return dynamicLink.shortUrl.toString();
}

如果用自定义Scheme,直接拼接myblog://article/$articleId即可,但没有未安装跳转的能力。

三、App内处理链接跳转

在App启动时监听动态链接,获取articleId并导航到详情页:

import 'package:flutter/material.dart';
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // 初始化Firebase
  await Firebase.initializeApp();
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    _initDynamicLinks();
  }

  void _initDynamicLinks() async {
    // 处理冷启动时的链接
    final PendingDynamicLinkData? initialLink = await FirebaseDynamicLinks.instance.getInitialLink();
    if (initialLink != null) {
      _handleDynamicLink(initialLink);
    }

    // 处理App后台运行时的链接
    FirebaseDynamicLinks.instance.onLink.listen((dynamicLinkData) {
      _handleDynamicLink(dynamicLinkData);
    });
  }

  void _handleDynamicLink(PendingDynamicLinkData data) {
    final Uri deepLink = data.link;
    // 解析articleId,比如链接是 https://xxx.page.link/article/123,或者 myblog://article/123
    final articleId = deepLink.pathSegments.last;
    if (articleId.isNotEmpty) {
      // 导航到文章详情页
      Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => ArticleDetailPage(articleId: articleId),
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const HomePage(),
    );
  }
}

// 文章详情页示例
class ArticleDetailPage extends StatelessWidget {
  final String articleId;
  const ArticleDetailPage({super.key, required this.articleId});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('文章详情')),
      body: FutureBuilder<DocumentSnapshot>(
        future: FirebaseFirestore.instance.collection('articles').doc(articleId).get(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            final article = snapshot.data!.data() as Map<String, dynamic>;
            final imageUrl = article['imageUrl']; // 从Firestore获取Storage中的图片URL
            return Column(
              children: [
                Image.network(imageUrl),
                Text(article['title']),
                Text(article['content']),
              ],
            );
          } else if (snapshot.hasError) {
            return Text('加载失败: ${snapshot.error}');
          }
          return const CircularProgressIndicator();
        },
      ),
    );
  }
}

四、测试验证

  • Android:用adb命令测试链接跳转:adb shell am start -W -a android.intent.action.VIEW -d "myblog://article/test123" com.your.app.package
  • iOS:在Xcode中通过Scheme测试,或者用Safari打开生成的动态链接

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 06:45:36