如何解决使用 Firebase 动态链接处理应用重定向的不同场景
我正在尝试创建一个流媒体应用。 我正在集成 Firebase 动态链接,因此主持人可以共享链接以加入他们的会话。 但是我对如何实施它有点迷茫,我想知道您对此的见解。
让我从结构开始,这是主要页面:
这就是我设置我的应用程序的方式,它们都包装到 Authenticate 小部件,该小部件确定是否应将用户重定向到登录或主页。很简单诶。 :)
然后是动态链接。 我的动态链接上有一个查询参数,以确定要加入的会话。它看起来像这样:
https://my.app.link/join-session?sessionId=\
这就是我想要处理的。
If (user is not logged in ) {
// save the sessionId to a singleton (or somewhere that persists along the app lifecycle,I use Provider here)
// redirects user to login page
// user logged in
// upon going to home page,will retrieve the saved sessionId and redirect user to the session using the sessionId
} else {
// retrieve sessionId
// redirect user to the session using the sessionId
}
这是我的代码的样子:
MainApp.dart 逻辑
....
if (state == PageLoadState.DONE) {
return MultiProvider(
providers: [
Provider<SampleAppAuthProvider>(
create: (_) => SampleAppAuthProvider(FirebaseAuth.instance),),Provider<SampleAppConfigProvider>(
create: (_) => SampleAppConfigProvider(sharedPrefs)
),StreamProvider(
initialData: null,create: (context) => context.read<SampleAppAuthProvider>().authState,Provider<DynamicLinkService>(create: (_) => DynamicLinkService(instance: FirebaseDynamicLinks.instance)),ChangeNotifierProvider(create: (_) => UsersApi(repo: Repository('users')),lazy: true),ChangeNotifierProvider(create: (_) => SessionsApi(repo: Repository('sessions')),ChangeNotifierProvider(create: (_) => MessagesApi(repo: Repository('messages')),],child: MaterialApp(
title: 'SampleApp!',theme: defaultTheme(),localizationsDelegates: context.localizationDelegates,supportedLocales: context.supportedLocales,locale: context.locale,onGenerateRoute: router.generateRoute,home: Authenticate(),);
}
......
这是我的身份验证页面:
class Authenticate extends StatelessWidget {
@override
Widget build(BuildContext context) {
context.read<DynamicLinkService>().handleDynamicLinks();
final firebaseUser = context.read<User>();
if (firebaseUser != null) {
return HomePage();
}
return LoginPage();
}
}
DynamicLinkService.dart
class DynamicLinkService {
DynamicLinkService({@required this.instance});
final FirebaseDynamicLinks instance;
String _sessionIdToJoin = '';
get sessionIdToJoin => _sessionIdToJoin;
void clearSessionId () => _sessionIdToJoin = '';
Future handleDynamicLinks() async {
final PendingDynamicLinkData data =
await instance.getinitialLink();
_handleDeepLink(data);
instance.onLink(
onSuccess: (PendingDynamicLinkData dynamicLink) async {
_handleDeepLink(dynamicLink);
},onError: (OnLinkErrorException e) async {
print('Link Failed: ${e.message}');
});
}
void _handleDeepLink(PendingDynamicLinkData data) {
final Uri deepLink = data?.link;
if (deepLink != null) {
print('_handleDeepLink | deeplink: $deepLink');
bool isJoiningSession = deepLink.pathSegments.contains('session');
if(isJoiningSession) {
String sessionId = deepLink.queryParameters['sessionId'];
if (sessionId != null) {
_sessionIdToJoin = sessionId;
}
}
}
}
}
Utils.dart
class Utils {
....
static Future<String> generateLink(String sessionId) async {
final DynamicLinkParameters parameters = DynamicLinkParameters(
uriPrefix: AppConfig.dynamicLinkBaseUrl,link: Uri.parse('${AppConfig.dynamicLinkBaseUrl}/join-session?sessionId=$sessionId'),dynamicLinkParametersOptions: DynamicLinkParametersOptions(
shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable
),androidParameters: AndroidParameters(
packageName: 'com.sample.app',minimumVersion: 0,);
final Uri dynamicUrl = await parameters.buildUrl();
final ShortDynamicLink shortenedLink =
await DynamicLinkParameters.shortenUrl(
dynamicUrl,DynamicLinkParametersOptions(
shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable),);
final Uri shortUrl = shortenedLink.shortUrl;
return AppConfig.dynamicLinkBaseUrl + shortUrl.path;
}
...
}
HomePage.dart:
class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
....
_navigatetoDestination() {
DynamicLinkService _service = context.select((DynamicLinkService service) => service);
String sessionToJoin = _service.sessionIdToJoin;
User user = context.read<User>();
if(sessionToJoin != '') {
_service.clearSessionId();
Navigator.pushNamed(context,AppRoutes.joinStream,arguments: StreamLiveArguments(
channelName: sessionToJoin,user: AppUtil.getName(user),role: ClientRole.Audience
)
);
}
}
@override
initState() {
super.initState();
WidgetsBinding.instance.addobserver(this);
_navigatetoDestination();
});
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(final AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
_navigatetoDestination();
}
}
....
}
这个实现的问题是有时它有效,有时它不起作用,我不知道为什么。 :(
我应该使用简单的类而不是提供者吗?如果是,我如何保留 sessionId?
我想处理的其他场景是当用户位于不同的页面(如个人资料页面)时。 此时,用户可以将应用程序最小化,并可以单击来自其他站点或 Messenger 的动态链接。 当应用程序恢复时,它将在 ProfilePage 中打开,在那里它没有处理动态链接(只有 HomePage 和 LoginPage 处理它)。我该如何补救?我应该为所有页面添加动态链接处理吗?或者我可以创建一个动态链接来重定向到我的应用程序中的某个页面吗?如果是,我该怎么做?
我在实施动态链接(以及提供者)方面有点新意,希望您对这个问题发表意见。提前致谢,我希望有人能帮助我或给我一些有关如何执行此操作的最佳实践的见解.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。