https://firebase.google.com/docs/dynamic-links/android/receive
states that
Calling getDynamicLink() retrieves the link and clears that data
The answer is in the documents:
You must call getDynamicLink() in every activity that might be launched by the link, even though the link might be available from the intent using getIntent().getData(). Calling getDynamicLink() retrieves the link and clears that data so it is only processed once by your app.
You normally call getDynamicLink() in the main activity as well as any activities launched by intent filters that match the link.
Duplicate the code written in MainActivity:onCreate
method (entire Firebase Dynamic Links related code) inside MainActivity:onNewIntent
method, this works irrespective of the app is running in the background or not.
Also MainActivity:onNewIntent
method is not invoked if the app is not present in background hence no duplicate Firebase call happens.
Your MainActivity should look like this
@Override
protected void onCreate(Bundle savedInstanceState) {
//...
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();
}
// Handle the deep link. For example, open the linked
// content, or apply promotional credit to the user's
// account.
// ...
})
.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.w(TAG, "getDynamicLink:onFailure", e);
}
});
}
@Override
protected void onNewIntent(Intent intent) {
//...
FirebaseDynamicLinks.getInstance()
.getDynamicLink(intent)
.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.
// ...
})
.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.w(TAG, "getDynamicLink:onFailure", e);
}
});
}
I kept a dirty hack by taking a global url and comparing it next time with new url , It's not perfect but it's the best I came up with .
var previousDeepLink:String?=null //take it as global and static
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();
}
if(previousDeepLink==deepLink?.toString()){
return@OnSuccessListener
}
previousDeepLink=deepLink?.toString()
// Handle the deep link. For example, open the linked
// content, or apply promotional credit to the user's
// account.
// ...
// ...
}
})
.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.w(TAG, "getDynamicLink:onFailure", e);
}
});