Firebase dynamic link not opening/launching my installed app [duplicate] - android

I have developed an android app locally on my device (app not yet on android play store). I have the following logic to get deep link in MainActivity.
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, null)
.addApi(AppInvite.API)
.build();
// Check if this app was launched from a deep link. Setting autoLaunchDeepLink to true
// would automatically launch the deep link if one is found.
boolean autoLaunchDeepLink = false;
AppInvite.AppInviteApi.getInvitation(mGoogleApiClient, this, autoLaunchDeepLink)
.setResultCallback(
new ResultCallback<AppInviteInvitationResult>() {
#Override
public void onResult(#NonNull AppInviteInvitationResult result) {
if (result.getStatus().isSuccess()) {
// Extract deep link from Intent
Intent intent = result.getInvitationIntent();
String deepLink = AppInviteReferral.getDeepLink(intent);
Toast.makeText(getApplicationContext(), deepLink, Toast.LENGTH_LONG).show();
// Handle the deep link. For example, open the linked
// content, or apply promotional credit to the user's
// account.
// ...
} else {
Log.d(TAG, "getInvitation: no deep link found.");
}
}
});
I built some dynamic links using Firebase console and open in mobile browser. But it is not opening my app and reaching to line String deepLink = AppInviteReferral.getDeepLink(intent);
Instead it is opening the URL in mobile browser itself.
How to open the app and handle deep link in activity while using firebase dynamic link??
Edit:
I have intent filter in the manifest file.
<activity android:name="MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<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>
</activity>

Action View and Action Main both are of different Intent category. So, you need to put them in different blocks like this:
<activity android:name=".DynamicLinkActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</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="example.com"
android:scheme="http" />
<data
android:host="example.com"
android:scheme="https" />
</intent-filter>
</activity>

Alternatively, you could also provide the data in your intent-filter, like stated in the "regular" deep links doc (https://developer.android.com/training/app-indexing/deep-linking.html)
The intent filter would then look like the following :
<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="https://XXYYZZ42.app.goo.gl/" // <- Replace with your deep link from the console
android:scheme="https"/>
</intent-filter>
That said link can be obtained in your console, right here :
EDIT : Added the picture to show where to find this link

Update January 2019
Ensure that you have added the SHA256 certificate fingerprint for your app into your project in the Firebase console.
Add the below code in the AndroidManifest.xml under the activity which you want the dynamic link to lunch:
<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="mydomainname.page.link" android:scheme="http"/>
<data android:host="mydomainname.page.link" android:scheme="https"/>
</intent-filter>
Remove android:autoVerify="true" if you have Android 6.0 (API level 23) and below or the app will crash.

As explained in another answer, your intent filter seems to have some problems. Also your url may have some problems. When I was playing with those, I had created faulty URL to FireBase web site without noticing it. It is possible to test you code by opening the whole url in your app. I wrote all urls to be tested to an email and sent to myself, open in the device and started clicking. After that you can create the url you want in FireBase. Below are few examples (typos and other errors possible):
If you clicked this url on your device:
https://<myapp>.app.goo.gl/?link=https://mysite.fi/112972&apn=com.mydomain.myapp
and had this in you manifest:
<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:scheme="https"
android:host="mysite.fi"
android:pathPattern=".*" />
</intent-filter>
It should open https://mysite.fi/112972 in your app (com.mydomain.myapp) and if you opened the link on your PC, it would open https://mysite.fi/112972 in the browser.
If you opened this url in your device:
https://<myapp>.app.goo.gl/?link=https://mysite.fi/112972&apn=com.mydomain.myapp&al=myscheme://mydeeplink/112972&afl=http://fallback.fi
and had this in you manifest:
<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:scheme="myscheme"
android:host="mydeeplink"
android:pathPattern=".*" />
</intent-filter>
It would open myscheme://mydeeplink/112972 in your app (com.mydomain.myapp). You would need to have code for handling it. If the app is not installed, it would open http://fallback.fi in your browser. On the PC it would still open https://mysite.fi/112972.
(edit 19.3.2018) It seems that Firebase does not fully support 'al=' anymore. The code works, but it is missing from the documentation and Firebase console generated urls.

I had the same problem with deep links not working and the former answers wasn't helping. What did the trick was splitting the "data" tag like this:
Instead of:
<data android:host="example.com" android:scheme="http"/>
<data android:host="example.com" android:scheme="https"/>
Do this:
<data android:host="example.com"/>
<data android:scheme="http"/>
<data android:scheme="https"/>
Hope that will help anyone else :)

Related

It is mandatory to specify the "android:host" for all url in android for Deep Link?

I have to filter two URL for an activity. I'm using Deep Links to App Content by specifying a url for the Deep Link Screen.
These are my urls
appdemo://deeplink
native://
I'm already added these two scheme to my Android Manifest file, looks like
<data android:scheme="appdemo" android:host="deeplink" />
<data android:scheme="native" />
my question is that, by providing scheme and host on the Android Manifest file, native:// this link does not work. it requires the android:host name also
(native://deeplink).
It is mandatory to specify the "android:host" for all url in android?
If no, how can i specify the different scheme.
The idea beside deep links is to use the same structure as normal links:
scheme://host/path
The main benefit is that you can teach your app even to open some Internet links, e.g. to open youtube (Android will ask, if you want to open in browser or YouTube app or your app):
<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:scheme="http"/>
<data android:scheme="https"/>
<data android:host="youtube.com"/>
<data android:host="www.youtube.com"/>
<data android:host="m.youtube.com"/>
<data android:host="youtu.be"/>
<data android:pathPattern=".*"/>
</intent-filter>
So, answering your questions:
Yes, it is mandatory to specify both scheme and host.
A good practice of handling two different links in one activity is to use different paths. Like this:
<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:scheme="appdemo" android:host="deeplink" android:pathPrefix="/path1/"/>
</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:scheme="appdemo" android:host="deeplink" android:pathPrefix="/path2/"/>
</intent-filter>
Then you can get your path in onNewIntent:
Uri data = intent.getData();
String path = data == null ? null : data.getPath();
...and build some logic depending on this path.
The above answer is acceptable and, in my case i want to navigate a new activity through this intent filter, and i got some information to the above answer and made some changes in my code and fix the issue.
Also I'm not specifying the host name for my second intent.
<activity
android:name=".DeepLinkActivity"
android:exported="true"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.Launcher">
<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:scheme="appdemo" android:host="deeplink" />
</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:scheme="native" />
</intent-filter>
</activity>
Now my both url navigate to DeepLinkActivity.
appdemo://deeplink
native://
Do you think this is not an optimized way?
Any other suggestions for that please mention.

How Can I Create an Intent to 'Open In App' but Not from the Browser

I've got an intent in my AndroidManifest.xml working great. When a person visits a page called "train", the actions specified in my ActivityMain are carried out.
However, my website includes some features which are not available in my app.
So i'd still like users to be able to navigate around my website with ease, without links to the train page on the browser opening the app.
Does anyone know how I can use an intent-filter to prompt the user with the option to "open in app" from apps such as Gmail, Messenger, etc, but NOT when they're on my website going to the specified page?
<intent-filter>
<data android:scheme="https"/>
<data android:host="example.co.uk"/>
<data android:path="/train/"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
<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.co.uk"
android:path="/train/"
android:scheme="https" />
</intent-filter>
For further information you can view detail here about deep linking:
https://developer.android.com/training/app-links

OAuth2 CallBack URL

I am doing OAuth2 authentication on Android. I get a "java.util.NoSuchElementException" error when trying to use the authorization code further down the line. After testing it seems that the call is correct, but I get nothing back..
My callback uri is set in the Settings Page, the Activity and the Manifest (see below). According to me it is not working because I am not in production.
One advice I received is to "set up your application as webapp", but it is not clear to me what steps I exactly have to take. Any advice?
Intent Filter set in the Manifest File.
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="https://fibi22cj69"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/> </intent-
filter>
Try like that:
<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="yourcallback.com"
android:scheme="oauth" />
</intent-filter>
And in the client, set the callback url to oauth://yourcallback.com

Launch app's activity when opening a specific link pattern

I have a little web app that sends anonymous messages as links.
I'm currently working on its Android version. The links of messages are in the pattern:
https://believe-labs.co/speak/m?somerandomkey
I want that when the receiver clicks the link of a message, and if the app is installed on the device, the browser should redirect the link to my app activity and launch it.
I tried
<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="believe-labs.co/m" android:scheme="https"/>
</intent-filter>
but it doesn't seem to work. Where am I wrong and what do I need to add?
You must use this kind of data (host & path):
<data
android:scheme="https"
android:host="believe-labs.co"
android:path="/speak/m" />
You shouldn't use believe-labs.co/m in the host,you can try the below code that will work for sure because i am also using same code in my app to be open via deeplink.
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data
android:host="believe-labs.co"
android:scheme="https"></data>
</intent-filter>

Firebase dynamic link not opening the app

I have developed an android app locally on my device (app not yet on android play store). I have the following logic to get deep link in MainActivity.
GoogleApiClient mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, null)
.addApi(AppInvite.API)
.build();
// Check if this app was launched from a deep link. Setting autoLaunchDeepLink to true
// would automatically launch the deep link if one is found.
boolean autoLaunchDeepLink = false;
AppInvite.AppInviteApi.getInvitation(mGoogleApiClient, this, autoLaunchDeepLink)
.setResultCallback(
new ResultCallback<AppInviteInvitationResult>() {
#Override
public void onResult(#NonNull AppInviteInvitationResult result) {
if (result.getStatus().isSuccess()) {
// Extract deep link from Intent
Intent intent = result.getInvitationIntent();
String deepLink = AppInviteReferral.getDeepLink(intent);
Toast.makeText(getApplicationContext(), deepLink, Toast.LENGTH_LONG).show();
// Handle the deep link. For example, open the linked
// content, or apply promotional credit to the user's
// account.
// ...
} else {
Log.d(TAG, "getInvitation: no deep link found.");
}
}
});
I built some dynamic links using Firebase console and open in mobile browser. But it is not opening my app and reaching to line String deepLink = AppInviteReferral.getDeepLink(intent);
Instead it is opening the URL in mobile browser itself.
How to open the app and handle deep link in activity while using firebase dynamic link??
Edit:
I have intent filter in the manifest file.
<activity android:name="MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<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>
</activity>
Action View and Action Main both are of different Intent category. So, you need to put them in different blocks like this:
<activity android:name=".DynamicLinkActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</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="example.com"
android:scheme="http" />
<data
android:host="example.com"
android:scheme="https" />
</intent-filter>
</activity>
Alternatively, you could also provide the data in your intent-filter, like stated in the "regular" deep links doc (https://developer.android.com/training/app-indexing/deep-linking.html)
The intent filter would then look like the following :
<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="https://XXYYZZ42.app.goo.gl/" // <- Replace with your deep link from the console
android:scheme="https"/>
</intent-filter>
That said link can be obtained in your console, right here :
EDIT : Added the picture to show where to find this link
Update January 2019
Ensure that you have added the SHA256 certificate fingerprint for your app into your project in the Firebase console.
Add the below code in the AndroidManifest.xml under the activity which you want the dynamic link to lunch:
<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="mydomainname.page.link" android:scheme="http"/>
<data android:host="mydomainname.page.link" android:scheme="https"/>
</intent-filter>
Remove android:autoVerify="true" if you have Android 6.0 (API level 23) and below or the app will crash.
As explained in another answer, your intent filter seems to have some problems. Also your url may have some problems. When I was playing with those, I had created faulty URL to FireBase web site without noticing it. It is possible to test you code by opening the whole url in your app. I wrote all urls to be tested to an email and sent to myself, open in the device and started clicking. After that you can create the url you want in FireBase. Below are few examples (typos and other errors possible):
If you clicked this url on your device:
https://<myapp>.app.goo.gl/?link=https://mysite.fi/112972&apn=com.mydomain.myapp
and had this in you manifest:
<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:scheme="https"
android:host="mysite.fi"
android:pathPattern=".*" />
</intent-filter>
It should open https://mysite.fi/112972 in your app (com.mydomain.myapp) and if you opened the link on your PC, it would open https://mysite.fi/112972 in the browser.
If you opened this url in your device:
https://<myapp>.app.goo.gl/?link=https://mysite.fi/112972&apn=com.mydomain.myapp&al=myscheme://mydeeplink/112972&afl=http://fallback.fi
and had this in you manifest:
<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:scheme="myscheme"
android:host="mydeeplink"
android:pathPattern=".*" />
</intent-filter>
It would open myscheme://mydeeplink/112972 in your app (com.mydomain.myapp). You would need to have code for handling it. If the app is not installed, it would open http://fallback.fi in your browser. On the PC it would still open https://mysite.fi/112972.
(edit 19.3.2018) It seems that Firebase does not fully support 'al=' anymore. The code works, but it is missing from the documentation and Firebase console generated urls.
I had the same problem with deep links not working and the former answers wasn't helping. What did the trick was splitting the "data" tag like this:
Instead of:
<data android:host="example.com" android:scheme="http"/>
<data android:host="example.com" android:scheme="https"/>
Do this:
<data android:host="example.com"/>
<data android:scheme="http"/>
<data android:scheme="https"/>
Hope that will help anyone else :)

Categories

Resources