如何用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
相关产品推荐
相关产品推荐

