I tried the below firebase official dynamic link sample but is not working for me.
Dynamic Link:
Mainfest:
<activity android:name=".java.MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- [START link_intent_filter] -->
<intent-filter >
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data
android:host="plpsoft.page.link"
android:scheme="https"/>
<data
android:host="plpsoft.page.link"
android:scheme="http"/>
</intent-filter>
<!-- [END link_intent_filter] -->
</activity>
Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
FirebaseDynamicLinks.getInstance()
.getDynamicLink(getIntent())
.addOnCompleteListener(new OnCompleteListener<PendingDynamicLinkData>() {
#Override
public void onComplete(#NonNull Task<PendingDynamicLinkData> task) {
Uri deepLink = null;
if (task.getResult() != null) {
deepLink=task.getResult().getLink();
((TextView) findViewById(R.id.linkViewReceive))
.setText(deepLink.toString());
}
}
})
.addOnSuccessListener(this, new OnSuccessListener<PendingDynamicLinkData>() {
#Override
public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) {
// Get deep link from result (may be null if no link is found)
Uri deepLink = null;
if (pendingDynamicLinkData != null) {
deepLink = pendingDynamicLinkData.getLink();
}
// Handle the deep link. For example, open the linked
// content, or apply promotional credit to the user's
// account.
// ...
// [START_EXCLUDE]
// Display deep link in the UI
if (deepLink != null) {
Snackbar.make(findViewById(android.R.id.content),
"Found deep link!", Snackbar.LENGTH_LONG).show();
((TextView) findViewById(R.id.linkViewReceive))
.setText(deepLink.toString());
} else {
Log.d(TAG, "getDynamicLink: no link found");
}
// [END_EXCLUDE]
}
})
.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e("Splash", "getDynamicLink:onFailure", e);
}
})
.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "getDynamicLink:onFailure", e);
}
});
}
While tapping the URL the app will launch successfully and i get the intent data URI string also. if i pass this URI to getDynamicLink() method it's return as null. I also add the both SHA1 and SHA256 key in firebase console.
I was able to fix it by removing the intent-filter from the manifest and adding the callback handler in the MainActivity.
What the docs says is that:
In the callback the PendingDynamicLinkData is returned in addOnSuccessListener(OnSuccessListener) or addOnCompleteListener(Activity, OnCompleteListener) which returns the most recently clicked dynamic link, or null if a dynamic link was not pending as captured data or in the intent.
So the deeplink was being captured by the intent filter and because it was not longer pending the callback returns null
Related
Am trying to track referrals from user1 to user2 using firebase. Here is what u did.
From the person inviting am generating following link
https://play.google.com/store/apps/details?id=com.mindedges.freegiveaway.freegiveaway&invitedby=xyzuser
So the receiver receives the above link which was generated by following code:
private void sendNativeInvites(){
String email = UserUtils.getCurrentUser(this).getEmail();
String packageName = getPackageName();
String link = "https://play.google.com/store/apps/details?id="+packageName+"&invitedby=" + email;
DynamicLink dynamicLink = FirebaseDynamicLinks.getInstance().createDynamicLink()
.setLink(Uri.parse(link))
.setDomainUriPrefix("https://freegiveaway.page.link")
.setAndroidParameters(
new DynamicLink.AndroidParameters.Builder(getPackageName()).build())
.buildDynamicLink();
Uri dynamicLinkUri = dynamicLink.getUri();
doSendInvite(dynamicLinkUri);
}
When the receiver clicks the link he will go to playstore and I expect that the app will be installed and launched with the above deep link.
On the main activity of the app i have following code to fetched the referrer but I cant find it.
private void fetchReferrerIfPresent(){
Log.d(TAG, "fetchReferrerIfPresent");
FirebaseDynamicLinks.getInstance()
.getDynamicLink(getIntent())
.addOnSuccessListener(this, new OnSuccessListener<PendingDynamicLinkData>() {
#Override
public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) {
// Get deep link from result (may be null if no link is found)
Uri deepLink = null;
if (pendingDynamicLinkData != null) {
deepLink = pendingDynamicLinkData.getLink();
}
Log.d(TAG,"deepLink = " + deepLink); //Getting null
if (deepLink != null && deepLink.getBooleanQueryParameter("invitedby", false)) {
referrerEmail = deepLink.getQueryParameter("invitedby");
Log.d(TAG, "Found referrerEmail. referrerEmail = " + referrerEmail);
}else{
Log.d(TAG, "No referrer found");
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG, "Exception while fetching referrerEmail", e);
}
});
}
In the manifest i have :
<activity
android:name="com.mindedges.freegiveaway.freegiveaway.LoginActivity"
android:label="#string/app_name"
android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<!--
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
-->
<data
android:host="freegiveaway.page.link"
android:scheme="https" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
How should be my android manifest file if I want to show my app in the chooser apps if someone clicks the dynamic link? The URL prefix is like -
https://testapp.page.link. At that stage if someone clicks the link then it first opens the browser then it redirects to my app. But I want to show my app in the chooser app list. At this time my manifest file is like follows-
<activity android:name=".extraActivities.DynamicLinkActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="test.com"
android:pathPattern="https://testapp.page.link*"
android:scheme="https"
/>
</intent-filter>
</activity>
We need to write intent-filter in the manifest file as follows-
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="testapp.com"
android:pathPattern=".*"
android:scheme="https" />
<data
android:host="testapp.page.link"
android:scheme="https"
android:pathPattern=".*"/>
</intent-filter>
Where "testapp.page.link" is the actually the URL prefixes shown at the top left corner of Firebase dynamic link console. And "testapp.com" is the first part of any link. Eg: https://testapp.com/user_profile?id="Zsdsdjwenncsdmsd". From this link, we can extract the user Id as "Zsdsdjwenncsdmsd" at the receiving end of the dynamic link. A complete example is shown below-
If anyone clicks share button this will create the dynamic link-
shareBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
shareProgressBar.setVisibility(View.VISIBLE);
Task<ShortDynamicLink> shortDynamicLinkTask = buildDeepLink(getString(R.string.grp_post_link)+postsModel.getPostId()+"&groupKey="+postsModel.getGroupKey()+"&groupName="+ dataSnapshot.getValue(String.class));
shortDynamicLinkTask.addOnCompleteListener(new OnCompleteListener<ShortDynamicLink>() {
#Override
public void onComplete(#NonNull Task<ShortDynamicLink> task) {
grpPostsViewHolder.shareProgressBar.setVisibility(View.GONE);
if(task.isSuccessful()){
Uri uri = task.getResult().getShortLink();
share(dataSnapshot.getValue(String.class), uri.toString());
}else {
Toast.makeText(context, "Can't create link", Toast.LENGTH_SHORT).show();
}
}
});
shortDynamicLinkTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
shareProgressBar.setVisibility(View.GONE);
}
});
The dynamic link creator function and share function-
/*-----------------------------------------------------------------------------*/
private Task<ShortDynamicLink> buildDeepLink(String deepLink) {
String uriPrefix = getString(R.string.dynamic_links_uri_prefix);
return FirebaseDynamicLinks.getInstance().createDynamicLink()
.setLink(Uri.parse(deepLink))
.setDomainUriPrefix(uriPrefix)
.setNavigationInfoParameters(new DynamicLink.NavigationInfoParameters.Builder()
.build())
.setAndroidParameters(new DynamicLink.AndroidParameters.Builder()
.setMinimumVersion(3)
.build())
.buildShortDynamicLink();
}
/*-----------------------------------------------------------------------------*/
private void share(String name, String deepLink) {
String message = "Find "+name+" on SelfieLe - link: "+deepLink;
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, message);
startActivity(intent);
}
/*---------------------------------------------------------------------------------*/
The String resources are-
R.string.grp_post_link, and R.string.dynamic_links_uri_prefix:
<string name="user_profile_link">https://testapp.com/user_profile?id=</string>
<string name="dynamic_links_uri_prefix">https://testapp.page.link</string>
At receiving end we can extract postId, groupKey etc as follows
FirebaseDynamicLinks.getInstance().getDynamicLink(getIntent()).addOnSuccessListener(this, new OnSuccessListener<PendingDynamicLinkData>() {
#Override
public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) {
if (pendingDynamicLinkData != null) {
deepLink = pendingDynamicLinkData.getLink();
}
if (deepLink != null) {
getGrpPost(deepLink.getQueryParameter("id"), deepLink.getQueryParameter("groupKey"), deepLink.getQueryParameter("groupName"));
}else {
Toast.makeText(DynamicLinkActivity.this, "Can't find link", Toast.LENGTH_SHORT).show();
}
}
}).addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(DynamicLinkActivity.this, "Can't find link", Toast.LENGTH_SHORT).show();
}
});
The getGroupPost(); is as follows
private void getGrpPost(String id, String groupKey, final String groupName) {
//Do what you want
}
Problem: Why is "Short dynamic links" created programatically wont open/launch the app directly?
I want to launch app directly when user clicks the dynamic url created dynamically by android app.
When clicking dynamic short link created dynamically by android app the following things happen,
1.Option show two options one is through chrome other is through app
2.if i choose chrome option, browser opens, shows a loading dialog box and launch app with PendingDynamicLinkData data
3.but if i choose app option, app lauches app but PendingDynamicLinkData is lost or null.
Any Help would be great. my manifest setting is below
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:host="myapp.page.link" android:scheme="http"/>
<data android:host="myapp.page.link" android:scheme="https"/>
</intent-filter>
You should handle your PendingDynamicLinkData in activity to override onCreate and onNewIntent. Like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (intent != null) {
handleDeepLink(intent);
}
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent != null) {
handleDeepLink(intent);
}
}
private void handleDeepLink(Intent intent) {
FirebaseDynamicLinks.getInstance().getDynamicLink(intent).addOnSuccessListener(pendingDynamicLinkData -> {
if (pendingDynamicLinkData != null) {
Uri deepLink = pendingDynamicLinkData.getLink();
if (deepLink != null) {
// todo .....
}
}
});
}
I don't know the correct solution but I have found a trick that works.
First make sure that you have added the following intent filter to the activity that is supposed to handle the dynamic link:
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="example.com"
android:scheme="http" />
<data
android:host="example.com"
android:scheme="https" />
</intent-filter>
Source
Then in your activity, use the following code to get the link:
String link=null;
if (getIntent().getData()!=null){
link=getIntent().getData().toString();
}
In the manifest, add the following intent filter to the activity that will handle the url:
override OnStart method of the target Activity:
public override fun onStart() {
super.onStart()
FirebaseDynamicLinks.getInstance()
.getDynamicLink(getIntent())
.addOnSuccessListener(this, new OnSuccessListener<PendingDynamicLinkData>() {
#Override
public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) {
// Get deep link from result (may be null if no link is found)
Uri deepLink = null;
if (pendingDynamicLinkData != null) {
deepLink = pendingDynamicLinkData.getLink();
}
// ...
}
})
.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "getDynamicLink:onFailure", e);
}
});
The complete guide here.
For some reason, i couldn't make it work in the same activity that as action MAIN.
I am trying to get query params from this
short dynamic link : https://easyloans.page.link/test
Long Dynamic Link : https://easyloans.page.link/?link=https://www.availfinance.in&apn=com.avail.easyloans.android&utm_campaign=Test_Campaign_Name&utm_medium=Test_Medium&utm_source=Test_Source
Manifest :
<activity android:name=".Activites.DynamicLink">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="easyloans.page.link"
android:scheme="http"
android:pathPrefix="/"
android:pathPattern=".*"/>
<data
android:host="easyloans.page.link"
android:scheme="https"
android:pathPrefix="/"
android:pathPattern=".*"/>
</intent-filter>
</activity>
In Android Activity:
FirebaseDynamicLinks.getInstance()
.getDynamicLink(getIntent())
.addOnSuccessListener(this, new OnSuccessListener<PendingDynamicLinkData>() {
#Override
public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) {
// Get deep link from result (may be null if no link is found)
Uri deepLink = null;
if (pendingDynamicLinkData != null) {
deepLink = pendingDynamicLinkData.getLink();
Log.d(TAG, "source : " + pendingDynamicLinkData.getLink().getQueryParameter("utm_source"));
}
Log.d(TAG, "link " + deepLink);
}
})
.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, "getDynamicLink:onFailure", e);
}
});
Output which i am receiving is :
link https://www.availfinance.in
and source : null (I am expecting Test_Source in this)
The getLink() method returns the link parameter you set on the long FDL, which in your example link was just what was returned: link=https://www.availfinance.in.
The UTM parameters are passed automatically to Google Analytics for Firebase.
pendingDynamicLinkData.getLink().getQueryParameter("foo") will return a value only if it is on the URL contained within the link parameter, e.g. if your link was link=https://www.availfinance.in/?foo=bar (with appropriate URL encoding).
I am implementing a shopping app.In that when a product is shared it should send a dynamic link so that when a person clicks it , opens in app only.Finally i achieved this feature.But when i am opening app from a shared dynamic link i am getting home page rather than product page.I need help regarding getting specific product page rather opening home page of shopping.
Here i am including code. AndroidManifest.xml
<activity android:name=".Postdetails">
<meta-data android:name="android.support.PARENT_ACTIVITY" android:value="MainActivity" />
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="postdetailsnew.com" android:scheme="https"
android:pathPattern=".*"/>
</intent-filter>
</activity>
PostDetails.java Here PostDetails page is the single product design page or activity .In this i wrote following code.
sharebutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
s="https://app_code.app.goo.gl/?link="+ProductLinkInBrowser+"&apn=com.example.maneesh.shop";
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, s);
sendIntent.setType("text/plain");
startActivity(sendIntent);
}
}
FirebaseDynamicLinks.getInstance().getDynamicLink(getIntent())
.addOnSuccessListener(this, new OnSuccessListener<PendingDynamicLinkData>() {
#Override
public void onSuccess(PendingDynamicLinkData pendingDynamicLinkData) {
// Get deep link from result (may be null if no link is found)
Uri deepLink = null;
if (pendingDynamicLinkData != null) {
deepLink = pendingDynamicLinkData.getLink();
FirebaseAppInvite invite=FirebaseAppInvite.getInvitation(pendingDynamicLinkData);
if(invite!=null){
String invitationId=invite.getInvitationId();
}
}
}
})
.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w("Heyy", "getDynamicLink:onFailure", e);
}
});
So here finally app main page is opened with dynamic link but not the specific product page which is shared.Please guide me to achieve this.
You need to parse the URL in the dynamic link, and fire an intent to send the user to the right part of your app. Generally you'll have the Dynamic Links listener set up in your main activity, and will route from there to any specific needs.
The deepLink variable in your code will be the URL your passed in the dynamic link, like http://yourshop.com/product/12345. You could call deepLink.getPath() which would return you product/12345, and then fire and intent for that, e.g:
String path = deepLink.getPath();
String[] parts = path.split("/")
if (parts[0] == "product") {
Intent intent = new Intent(this, PostDetails.class);
intent.putExtra("productid", parts[1]);
startActivity(intent);
}