I am creating a flutter application. I am using Deeplink. It is creating success but the clicking part of the app not working well. The app is retrieving the url but not retrieving the params. I don't know what is the reason?
My codes are shown below.
final DynamicLinkParameters parameters = DynamicLinkParameters(
uriPrefix: 'https://mydomain.page.link',
link: Uri.parse(
// 'https://pachiradev.page.link/circleinvite?token=' + uid1.toString()
'https://pachiradev.page.link/circleinvite?token=' + '1234'),
androidParameters: AndroidParameters(
packageName: 'io.flutter.plugins.firebasedynamiclinksexample',
minimumVersion: 0,
),
dynamicLinkParametersOptions: DynamicLinkParametersOptions(
shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short,
),
iosParameters: IosParameters(
bundleId: 'com.google.FirebaseCppDynamicLinksTestApp.dev',
minimumVersion: '0',
),
);
Uri url;
final ShortDynamicLink shortLink = await parameters.buildShortLink();
url = shortLink.shortUrl;
print(url)
//https://mydomain.page.link/circleinvite?token=1234
//https://mydomain.page.link/ARTu
Here I printing the url with params. But in retrieving code I am not getting params
FirebaseDynamicLinks.instance.onLink(
onSuccess: (PendingDynamicLinkData dynamicLink) async {
final Uri deepLink = dynamicLink?.link;
print(deepLink);
//https://mydomain.page.link/circleinvite
//not showing params
if (deepLink != null) {
// Navigator.pushNamed(context, deepLink.path);
final queryParams = deepLink.queryParameters;
if (queryParams.length > 0) {
String token = queryParams["token"];
}
}
}, onError: (OnLinkErrorException e) async {
print('onLinkError');
print(e.message);
});
I tried several way but no results. If anyone know the reason please help me.
I found that we need to put proper app package name.
androidParameters: AndroidParameters(
packageName: 'com.myapp.android',
minimumVersion: 0,
),
dynamicLinkParametersOptions: DynamicLinkParametersOptions(
shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short,
),
iosParameters: IosParameters(
bundleId: 'com.myapp.ios',
minimumVersion: '0',
),
Related
**I build a chat app and I am trying to apply the cloud function to my app so every time user sends a message the other one receives a notification but I have a problem I send the message twice so that I can show both messages on chat screen and also when user add friend I add twice for both user **
// chat provider
class ChatScreenProvider with ChangeNotifier {
final _chatAuth = FirebaseFirestore.instance;
// static String? friendPhone;
Future<void> addMesseges({
BuildContext? context,
String? messages,
String? userId,
String? userName,
chatUserId,
String? userPhone,
required String? freindPhone,
}) async {
enter image description herefinal friendUserId = await FirebaseFirestore.instance
.collection(conUserCollectios)
.doc(userPhone)
.collection(conFriendCollection)
.doc(freindPhone)
.get();
// final chatId = friendUserId[conChatId];
_chatAuth
.collection(conUserCollectios)
.doc(userPhone)
.collection(conFriendCollection)
.doc(freindPhone)
.collection(conChatCollectios)
.doc()
.set(
{
conUserId: userId,
conChatMesseges: messeges,
conuserName: userName,
conChatCreatedAt: Timestamp.now(),
conChatUserId: friendUserId[conFriendPhone],
conFriendUserName: friendUserId[conFriendUserName] == null
? freindPhone
: friendUserId[conFriendUserName]
},
).then((value) {
_chatAuth
.collection(conUserCollectios)
.doc(freindPhone)
.collection(conFriendCollection)
.doc(userPhone)
.collection(conChatCollectios)
.doc()
.set(
{
conUserId: userId,
conChatMesseges: messeges,
conuserName: userName,
conChatCreatedAt: Timestamp.now(),
conChatUserId: friendUserId[conFriendPhone],
conFriendUserName: friendUserId[conFriendUserName] == null
? freindPhone
: friendUserId[conFriendUserName]
},
);
});
}
}
// add friend provider
class AddFriendProvider with ChangeNotifier {
final _friendAuth = FirebaseFirestore.instance;
Future<void> addFriends({
// required String? friendName,
required String? friendNumber,
required userPhone,
// required userName,
BuildContext? context,
}) async {
final friendUser = await FirebaseFirestore.instance
.collection(conUserCollectios)
.doc(friendNumber)
.get();
final currentUser = await FirebaseFirestore.instance
.collection(conUserCollectios)
.doc(userPhone)
.get();
final users =
await FirebaseFirestore.instance.collection(conUserCollectios).get();
final userList = users.docs.map((e) => e.data()).toList();
final element = userList.firstWhere(
(element) => element[conuserPhone] == friendNumber,
orElse: () => {},
);
if (element[conuserPhone] == userPhone || element.isEmpty) {
AwesomeDialog(
padding: EdgeInsets.all(10),
context: context!,
dialogType: DialogType.ERROR,
body: Column(children: [
element[conuserPhone] != userPhone
? Text(
'the user is not found',
style: TextStyle(color: Colors.black, fontSize: 20),
)
: Text(
'يعم ده انت ',
style: TextStyle(color: Colors.black, fontSize: 20),
),
SizedBox(height: 20),
element[conuserPhone] != userPhone
? Text(
'invite your friend \n to use our app',
style: TextStyle(color: Colors.red, fontSize: 15),
)
: Text(
'بلاش هزارك الرخم ده',
style: TextStyle(color: Colors.red, fontSize: 15),
),
]),
btnOkText: 'Cancel',
btnOkOnPress: () {},
).show();
} else {
// String? chatId = friendNumber! + userPhone;
_friendAuth
.collection(conUserCollectios)
.doc(currentUser[conuserPhone])
.collection(conFriendCollection)
.doc(friendNumber)
.set(
{
conFriendUserName: friendUser[conuserName],
conFriendPhone: friendUser[conuserPhone],
conuserPhone: currentUser[conuserPhone],
conuserName: currentUser[conuserName],
conUserImageUrl: friendUser[conUserImageUrl],
conFriendId: friendUser[conUserId],
// conChatId: chatId
},
).then((value) async {
final userDoc = FirebaseFirestore.instance
.collection(conUserCollectios)
.doc(userPhone)
.collection(conFriendCollection)
.doc();
// final data = userDoc.docs.map((e) => e.data()).toList();
print(userDoc);
// print(userDoc.docs.toString());
// print(userDoc.docChanges);
_friendAuth
.collection(conUserCollectios)
.doc(friendUser[conuserPhone])
.collection(conFriendCollection)
.doc(currentUser[conuserPhone])
.set(
{
conFriendUserName: currentUser[conuserName],
conFriendPhone: currentUser[conuserPhone],
conuserPhone: friendUser[conuserPhone],
conuserName: friendUser[conuserName],
conUserImageUrl: currentUser[conUserImageUrl],
conFriendId: currentUser[conUserId],
// conChatId: chatId
},
);
});
Navigator.of(context!).pushReplacementNamed(MultiUserChats.routeNames);
}
}
}
I am creating custom dynamic link as given below:
Future<String> generateDynamicLink(
String pid, String imgurl, String title, String description) async {
final DynamicLinkParameters parameters = DynamicLinkParameters(
uriPrefix: uriPrefix,
link: Uri.parse(
uriPrefix+'/pd?pid=$pid',
),
androidParameters: AndroidParameters(
packageName: 'com.test',
minimumVersion: 0,
),
socialMetaTagParameters: SocialMetaTagParameters(
description: description,
imageUrl: Uri.parse(
imgurl,
),
title: title,
),
dynamicLinkParametersOptions: DynamicLinkParametersOptions(
shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable,
),
);
Uri url = await parameters.buildUrl();
ShortDynamicLink shortenedLink = await DynamicLinkParameters.shortenUrl(
url,
DynamicLinkParametersOptions(
shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable),
);
return shortenedLink.shortUrl.toString();
}
And handling the receiving part by calling the fetchLinkData (see below) inside the initState of my home page
void fetchLinkData(BuildContext context) async {
var link = await FirebaseDynamicLinks.instance.getInitialLink();
handleLinkData(link, context);
FirebaseDynamicLinks.instance.onLink(
onSuccess: (PendingDynamicLinkData dynamicLink) async {
handleLinkData(dynamicLink, context);
},
onError: (OnLinkErrorException error) async {
print(error.message);
},
);
}
void handleLinkData(PendingDynamicLinkData data, BuildContext context) async {
final Uri uri = data?.link;
if (uri != null) {
final queryParams = uri.queryParameters;
if (queryParams.keys.contains("pid")) {
String pid = queryParams["pid"];
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ProductScreen(id: pid),
),
);
}
}
}
Now my problem is, On emulator everything works as expected and when the dynamic link is opened it navigates to the correct page but when I try on my android device only the app is opened.
If anyone else is having the same problem, removing the intent filter solved the problem for me.
I am creating a dynamic link to navigate me to a specified page, when trying it on emulator it work fine but when trying it on actual device the link only open the app
Creating the dynamic link
Future<void> createDynamicLink(bool short, int lecID, String lecName) async{
setState(() {
_isCreatingLink = true;
});
final DynamicLinkParameters parameters = DynamicLinkParameters(
uriPrefix: 'https://geneapp.page.link',
link: Uri.parse('https://www.geneapp.com/lecture?lecID=$lecID&lecName=$lecName'),
androidParameters: AndroidParameters(packageName: 'com.example.teams',minimumVersion: 0),
dynamicLinkParametersOptions: DynamicLinkParametersOptions(
shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short
),
socialMetaTagParameters: SocialMetaTagParameters(
title: "$lecName",
description: "new"
)
);
print("https://geneapp.page.link/lecture?lecID=$lecID&lecName=$lecName");
Uri url;
if (short) {
final ShortDynamicLink shortLink = await parameters.buildShortLink();
url = shortLink.shortUrl;
} else {
url = await parameters.buildUrl();
}
setState(() {
_linkMessage = url.toString();
_isCreatingLink = false;
});
print(url);
Clipboard.setData(new ClipboardData(text: '$url'));
FocusScope.of(context).requestFocus(new FocusNode());
scaffoldKey.currentState?.removeCurrentSnackBar();
scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text("copied",style: TextStyle(fontSize: 16)),
Padding(
padding: EdgeInsets.fromLTRB(10.0,0.0,0.0,0.0),
child: Icon(Icons.check_circle,color: Colors.grey,),
)
],
),
backgroundColor: Colors.green,
duration: Duration(seconds: 3),
));
}
Handling the deep link:
void initDynamicLinks() async{
FirebaseDynamicLinks.instance.onLink(
onSuccess: (PendingDynamicLinkData dynamicLink) async {
final Uri deepLink = dynamicLink?.link;
if (deepLink != null) {
var isLec = deepLink.pathSegments.contains('lecture');
if(isLec){
var lecName = deepLink.queryParameters['lecName'];
var lecID = int.parse(deepLink.queryParameters['lecID']);
print("initDynamicLinks | lecName : $lecName lecID : $lecID");
await _openPDF(lecName, lecID);
}
}
else
print('its null');
}, onError: (OnLinkErrorException e) async {
print('onLinkError');
print(e.message);
});
final PendingDynamicLinkData data = await FirebaseDynamicLinks.instance.getInitialLink();
final Uri deeplink = data?.link;
if(deeplink != null){
var lecName = deeplink.queryParameters['lecName'];
var lecID = int.parse(deeplink.queryParameters['lecID']);
print("initDynamicLinks | lecName : $lecName lecID : $lecID");
await _openPDF(lecName, lecID);
}
}
_openPDF(String lecName, int lecID) async{
final filename = lecName;
String dir = (await getApplicationDocumentsDirectory()).path;
if (await File('$dir/$filename').exists()){
navigatorKey.currentState.pushNamed('/pdf', arguments: '$dir/$filename');
}
else{
//..
//
navigatorKey.currentState.pushNamed('/pdf', arguments: '$dir/$filename');
}
}
in my main build function I am setting initialRoute to a splash screen,
then in my splash screen initstate I am calling the initDynamicLinks():
There can be various reasons for app not launching, the android device your using, the browser used to launch the link (if a link is copy pasted in chrome they do not work), DynamicLinks setup.
You can try few things
encode your lecName variable in the Long URL.
Send the dynamic-short link over message and try to click and launch the app.
i am using firebase dynamic link and it is working in google chrome , messenger , whatsapp but not working in facebook browser it is opening play store
my code to create dynamic link
Future<String> _createDynamicLink(id) async {
final DynamicLinkParameters parameters = DynamicLinkParameters(
uriPrefix: "http://applic.page.link",
link: Uri.parse("https://applic.page.link/heloo"),
androidParameters: AndroidParameters(
packageName: com.examole.myapp,
minimumVersion: 0,
),
dynamicLinkParametersOptions: DynamicLinkParametersOptions(
shortDynamicLinkPathLength: ShortDynamicLinkPathLength.short,
),
iosParameters: IosParameters(
bundleId: 'com.google.FirebaseCppDynamicLinksTestApp.dev',
minimumVersion: '0',
),
);
Uri url;
final ShortDynamicLink shortLink = await parameters.buildShortLink();
url = shortLink.shortUrl;
setState(() {
_linkMessage = url.toString();
});
return _linkMessage;
}
my code to fetch the link
void initDynamicLinks() async {
final PendingDynamicLinkData data =
await FirebaseDynamicLinks.instance.getInitialLink();
final Uri deepLink = data?.link;
if (deepLink != null) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HelooPage()));
}
FirebaseDynamicLinks.instance.onLink(
onSuccess: (PendingDynamicLinkData dynamicLink) async {
final Uri deepLink = dynamicLink?.link;
if (deepLink != null) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HelooPage()));
}
},
onError: (OnLinkErrorException e) async {
print('onLinkError');
print(e.message);
});
}
i use flutter android studio
Can you please tell me how to Send and fetch the arguments using the flutter plugin firebase_dynamic_links[https://pub.dev/packages/firebase_dynamic_links#-readme-tab-]?
I want to pass parameters like username and password in the deeplink/dynamic link as follow :
uriPrefix: 'https://test.page.link/appinvite?username=Test&password=123456',
link: Uri.parse('https://test.page.link/appinvite?username=Test&password=123456'),
Is this the correct way to pass the data ?
After that i am using below code to fetch data,
await FirebaseDynamicLinks.instance.getInitialLink();
final Uri deepLink = data?.link;
But, it is providing me the dummy web URL i have added in the firebase console for firebase dynamic links in Deep Link URL
currently i am able to open the app from firebase dynamic link but, unable to fetch custom parameters.
Any help will be appreciated.
Updated Code :
For sending invite :
_generateAndShareDynamicLink() async {
final DynamicLinkParameters parameters = DynamicLinkParameters(
uriPrefix: 'https://test.page.link/groupinvite',
link: Uri.parse('https://test.page.link/groupinvite'),
androidParameters: AndroidParameters(
packageName: 'com.test.flutter_authentication',
minimumVersion: 0,
),
dynamicLinkParametersOptions: DynamicLinkParametersOptions(
shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable,
),
);
Uri url = await parameters.buildUrl();
shareURL(Uri.https(url.authority, url.path, {"username": "Test"}));
}
For fetching data inside initState() :
FirebaseDynamicLinks.instance.onLink(
onSuccess: (PendingDynamicLinkData dynamicLink) async {
final Uri deepLink = dynamicLink?.link;
_scaffoldKey.currentState.showSnackBar(SnackBar(content: Text("deepLink2 : ${deepLink}",)));
if (deepLink != null) {
Map sharedListId = deepLink.queryParameters;
print("sharedListId : ${sharedListId}");
String username=sharedListId["username"];
print("username : ${username}");
Navigator.pushNamed(context, deepLink.path);
}
}, onError: (OnLinkErrorException e) async {
print('onLinkError');
print(e.message);
});
Still retrieved data is null.
Can anybody help ?
The best way to use dynamic links are,
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
import 'package:flutter/material.dart';
class TestPage extends StatefulWidget {
#override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
#override
void initState() {
super.initState();
fetchLinkData();
}
void fetchLinkData() async {
// FirebaseDynamicLinks.getInitialLInk does a call to firebase to get us the real link because we have shortened it.
var link = await FirebaseDynamicLinks.instance.getInitialLink();
// This link may exist if the app was opened fresh so we'll want to handle it the same way onLink will.
handleLinkData(link);
// This will handle incoming links if the application is already opened
FirebaseDynamicLinks.instance.onLink(onSuccess: (PendingDynamicLinkData dynamicLink) async {
handleLinkData(dynamicLink);
});
}
void handleLinkData(PendingDynamicLinkData data) {
final Uri uri = data?.link;
if(uri != null) {
final queryParams = uri.queryParameters;
if(queryParams.length > 0) {
String userName = queryParams["username"];
// verify the username is parsed correctly
print("My users username is: $userName");
}
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Sample"),
),
body: Center(
child: Text("Test"),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
var dynamicLink = await createDynamicLink(userName: "Test");
// dynamicLink has been generated. share it with others to use it accordingly.
print("Dynamic Link: $dynamicLink");
},
child: Icon(
Icons.add,
color: Colors.white,
),
),
);
}
Future<Uri> createDynamicLink({#required String userName}) async {
final DynamicLinkParameters parameters = DynamicLinkParameters(
// This should match firebase but without the username query param
uriPrefix: 'https://test.page.link',
// This can be whatever you want for the uri, https://yourapp.com/groupinvite?username=$userName
link: Uri.parse('https://test.page.link/groupinvite?username=$userName'),
androidParameters: AndroidParameters(
packageName: 'com.test.demo',
minimumVersion: 1,
),
iosParameters: IosParameters(
bundleId: 'com.test.demo',
minimumVersion: '1',
appStoreId: '',
),
);
final link = await parameters.buildUrl();
final ShortDynamicLink shortenedLink = await DynamicLinkParameters.shortenUrl(
link,
DynamicLinkParametersOptions(shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable),
);
return shortenedLink.shortUrl;
}
}
You're done.
This worked for me
The sending side:
Future<String> generateLink() async {
final DynamicLinkParameters parameters = DynamicLinkParameters(
uriPrefix: 'https://<your-domain-name>.page.link',
link: Uri.parse(
'https://<your-domain-name>.page.link/<your-route>/?id=acb&name=me'), // <- your paramaters
dynamicLinkParametersOptions: DynamicLinkParametersOptions(
shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable),
androidParameters: AndroidParameters(
packageName: '<package-name>',
minimumVersion: 0,
),
socialMetaTagParameters: SocialMetaTagParameters(
title: "click the link",
),
);
final Uri dynamicUrl = await parameters.buildUrl();
final ShortDynamicLink shortenedLink =
await DynamicLinkParameters.shortenUrl(
dynamicUrl,
DynamicLinkParametersOptions(
shortDynamicLinkPathLength: ShortDynamicLinkPathLength.unguessable),
);
final Uri shortUrl = shortenedLink.shortUrl;
return "https://<your-domain-name>.page.link" + shortUrl.path;
}
The receiving side:
FirebaseDynamicLinks.instance.onLink(
onSuccess: (PendingDynamicLinkData dynamicLink) async {
final Uri deepLink = dynamicLink?.link;
if (deepLink != null) {
print(deepLink.queryParameters['id']); // <- prints 'abc'
}
}, onError: (OnLinkErrorException e) async {
print('onLinkError');
print(e.message);
}
);