I'm developing web app and I share my contents using Facebook, the issue I'm facing is when someone clicks on the link posted on Facebook sometimes it opens using Facebook in app browser and that causes many issues.
Is there a way to prevent Facebook from opining my links and use the device default browser instead?
I couldn't get my js dynamic grid to run in the Facebook in-app browser, but I couldn't just leave it up to the user to figure out what was wrong and that they needed to open in a real browser.
I used js to detect the Facebook in-app browser and tried using a js alert to inform the user that they needed to 'open in safari', but alerts don't work consistently or reliably with the Facebook in-app browser.
I found that a redirect to a user alert page was the most reliable solution. It can be presented as you wish (modal, etc.) A code sample for the redirect is included. Note that the redirect page remains within the Facebook browser - only user interaction can break out. I used my redirect page to tell people to use the 'share > open in Safari' function.
When the user clicks on 'open in safari', the redirect page reloads in safari, detects that it is now NOT in the Facebook in-app browser, and automatically redirects the user back to the page they wanted in the first place, but no longer from within the Facebook in-app browser. A "one-click" workaround to get the user out of that in-app browser.
The best solution would still be for my js grids to 'just work' in the Facebook browser some day. If anyone figures it out, let me know.
<!-- check if running in facebook app -->
<script>
var ua = navigator.userAgent || navigator.vendor || window.opera;
function isFacebookApp() {
return (ua.indexOf("FBAN") > -1) && (ua.indexOf("FBAV") > -1);
}
if (isFacebookApp()) {
window.parent.location.assign("https://yourdomain.com/redirect_page/index.html");
}
</script>
It is completely up to the user, there is no way to force opening it in the default browser instead. There is more information (and some answers) in this thread: File upload control not working in Facebook In-App Browser
OR... be less complicated. Why have a function called isFacebookApp() at all, and why target Opera when you are looking only for the FB in-app browser only?
<script>
var ua = navigator.userAgent;
if (ua.indexOf("FBAN") != -1 || ua.indexOf("FBAV") != -1) {
if (!window.location.href.match('redirect_fb')) {
window.location.href = "https://example.com/redirect_fb";
}
}
</script>
Thank you to both of you though. This was driving me nuts. My main problem was fonts being enlarged on my Android. Now I find reducing with a fontsz = Math.round(fontsz*.7)is perfect to counteract (when FB app detected)
Based on Mcbeese
<!-- check if running in facebook app -->
<script>
var ua = navigator.userAgent || navigator.vendor || window.opera;
function isFacebookApp() {
return (ua.indexOf("FBAN") > -1) || (ua.indexOf("FBAV") > -1);
}
if (isFacebookApp()) {
if (!window.location.href.match('redirect_fb')) {
window.location.href = "https://example.com/redirect_fb";
}
}
</script>
I found that Android will open Firebase Dynamic Links by external browser regardless of which kind of webview the url was posted.
I wrote a more detailed description at https://stackoverflow.com/a/56143217/3000586.
Related
When opened in Messenger or Facebook, my custom deep link does not open my native app anymore but shows the App Store instead, while it's still working effectively in Safari, SMS, Whatsapp apps...
Flow is pretty standard :
user clicks on an url redirecting to a web page opening the App Store if scheme_based url fails - code snippet:
var loadedAt = +new Date;
setTimeout(
function() {
if (+new Date - loadedAt < 2000){
window.location = appstoreFail;
}
}
,25);
//Try launching the app using URL schemes
window.open(appUrlScheme,"_self");
Any idea why Facebook is not recognizing app scheme urls? Did they change anything? Facebook or Messenger are opening a web view, so there might be something with it but I've the feeling it was working before and stoped working recently...
Thank you very much for your suggestion, or any workaround to open a native app from Facebook/Messenger!
Lucas
Facebook can do whatever they want with any network request in their app and it seems that they choose to block non-http requests in recent versions of their app...
So I'm looking to launch a mobile app when a web page is landed on. I've seen this done and all is great there (see code below with Facebook and Pandora as an example). But I'm looking for a logic check to route the user one way or the other depending upon the successful or unsuccessful launch of the app. It was said in a previous solution that you cannot use a link to check the user's mobile device to see if an app is installed, but I keep thinking that there might be a way to see if the user's app was successfully launched after-the-fact and route them based on that.
Using the code below, if the app is launched, the web page falls away, if you will (disappears into the background while the app takes center stage). If, however, the app isn't installed on the mobile device, then the web page stays up and you get an error (can't recall off-hand which error). But it seems to me that receipt of this error should be able to trigger a re-routing to a specific URL of your choice. Not at the server-level, but at the code-level. In other words... if the app launches, then grats... enjoy! But if the page loads with an error, then it redirects instantly to say, the app download page on Apple or Google (depending upon the OS detected).
Does anyone have a suggestion as to how to make this happen? Essentially one piece of code that is looking for the trigger error and reacting to that as a way to A) launch the app from a page load (link) B) open the app store in a browser to download the app if the app wasn't successfully launched.
This is my first foray into Stack, but I have found the community very helpful over the years.
<script type="text/javascript"> // <![CDATA[
var isMobile = {
Android: function() {
return navigator.userAgent.match(/Android/i);
},
BlackBerry: function() {
return navigator.userAgent.match(/BlackBerry/i);
},
iOS: function() {
return navigator.userAgent.match(/iPhone|iPad|iPod/i);
},
Opera: function() {
return navigator.userAgent.match(/Opera Mini/i);
},
Windows: function() {
return navigator.userAgent.match(/IEMobile/i);
},
any: function() {
return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
}
};
if ( isMobile.Android() ) {
document.location.href = "fb://profile";
}
else if(isMobile.iOS())
{
document.location.href="pandora://";
}
</script>
What you're talking about is called Deferred Deep Linking in terms of App Links. If you were coding an app that wanted to utilize this, there are iOS guides and Android ones. Overall, there doesn't seem to be a standard implementation for all scenarios, however, there is a pretty simple "roll-your-own" implementation that is similar to what you're attempting.
(from another SO answer)
<script type="text/javascript">
window.onload = function() {
// Deep link to your app goes here
document.getElementById("l").src = "my_app://";
setTimeout(function() {
// Link to the App Store should go here -- only fires if deep link fails
window.location = "https://itunes.apple.com/us/app/my.app/id123456789?ls=1&mt=8";
}, 500);
};
</script>
<iframe id="l" width="1" height="1" style="visibility:hidden"></iframe>
As a commentor said above, use an iframe so you can keep processing code even if your window.location fails. Then, set up a simple setTimeout with a reasonable fallback time. You don't need to catch any error messages or response headers. If the app didn't launch, then a website will.
Just thought to add, since you want A) Launch App from link and upon failure B) Go to store to download the app.
A Cross-Platform solution you can use rather than rolling your own as an alternative, I'd suggest trying Firebase Dynamic Links (works on both Android and iOS) and its free.
It also has the benefit of providing your app the link information, like if you put in the link an article ID (from your news website example), then the app can load up that article upon launch, and it persists even if the user has to install the app from the store, when launched it will open to that article you specified in the link.
In addition, Dynamic Links work across app installs: if a user opens a Dynamic Link on iOS or Android and doesn't have your app installed, the user can be prompted to install it; then, after installation, your app starts and can access the link.
https://firebase.google.com/docs/dynamic-links
With very little code you can add the ability for a user to click a link on your mobile web and be taken to the corresponding page in your app, even if they have to go to the App Store or Google Play Store to install it first!
https://firebase.google.com/docs/dynamic-links/use-cases/web-to-app
I have a webpage, lets call it entry.html.
When a user enters this page, a javascript code (see below) is attempting to deep-link the user to the native iOS / Android app.
If the deep-link fails (probably if the app isn't installed on device), user should "fall back" to another page- lets call it fallback.html.
here is the javascript code that is running on entry.html:
$(function(){
window.location = 'myapp://';
setTimeout(function(){
window.location = 'fallback.html';
}, 500);
});
this is a standard deep-linking method that is recommended all over the network; try to deep-link, and if the timeout fires it means that deep-link didn't occur- so fallback.
this works fine, as long app is installed on device.
but if the app isn't installed, this is the behaviour when trying to deep-link:
Mobile Safari: I see an alert message saying "Safari cannot open this page..." for a moment, and then it falls-back properly to fallback.html- which is the expected behaviour.
Mobile Chrome is my problem.
when the app isn't installed, browser is actually redirected to the myapp:// url, which is of course, invalid- so i get a "not found" page, and fall-back doesn't occur.
Finally- my question is:
How can I fix my code so FALL-BACK WILL OCCUR on mobile Chrome as well? just like mobile Safari?
note: i see that LinkedIn mobile website does this properly, with Safari & Chrome, with or without the app installed, but i couldn't trace the code responsible for it :(
note2: i tried appending an iframe instead of window.location = url, this works only on Safari, mobile Chrome doesn't deep-link when appending an iFrame even if app is installed.
Thanks all!
UPDATE:
i found a decent solution, and answered my own question. see accepted answer for my solution.
for whoever is interested, i managed to find a decent solution to solve these issues with deeplinking Chrome on Android.
i abandoned the myapp:// approach, i left it functioning only in cases of an iOS device.
for Android devices, i'm now using intents which are conceptually different than the myapp:// protocol.
I'm mainly a web developer, not an Android developer, so it took me some time to understand the concept, but it's quite simple. i'll try to explain and demonstrate MY solution here (note that there are other approaches that could be implemented with intents, but this one worked for me perfectly).
here is the relevant part in the Android app manifest, registering the intent rules (note the android:scheme="http" - we'll talk about it shortly):
<receiver android:name=".DeepLinkReceiver">
<intent-filter >
<data android:scheme="http" android:host="www.myapp.com" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
now, after this is declared in the app manifest, i'm sending myself an email with "http://www.myapp.com" in the message.
when link is tapped with the Android device, a "chooser" dialog comes up, asking with which application i want to open the following? [chrome, myapp]
the reason this dialog came up upon tapping on a "regular" url, is because we registered the intent with the http scheme.
with this approach, the deeplink isn't even handled in the webpage, it's handled by the device itself, when tapping a matching link to an existing intent rule defined in the Android app manifest.
and yes, as i said, this approach is different by concept than the iOS approach, which invokes the deeplink from within the webpage, but it solves the problem, and it does the magic.
Note: when app isn't installed, no chooser dialog will come up, you'll just get navigated to the actual web page with the given address (unless you have more than 1 browser, so you'll need to choose one... but lets not be petty).
i really hope that this could help someone who's facing the same thing.. wish i had such an explanation ;-)
cheers.
It is very important to make sure that when you try to open a deeplink URL with JavaScript that the URL is properly formatted for the device and browser. (If you do not use the appropriate deeplink URL for the browser/platform, a user may be redirected to a “Page Not Found”, which is what you experience.)
Now you must note that Chrome on Android has a different URL format than the old standard Android browser 1! You need to annotate the deep links using href="android-app://" in the HTML markup of your web pages. You can do this in the section for each web page by adding a tag and specifying the deep link as an alternate URI.
For example, the following HTML snippet shows how you might specify the corresponding deep link in a web page that has the URL example://gizmos.
<html>
<head>
<link rel="alternate"
href="android-app://com.example.android/example/gizmos" />
...
</head>
<body> ... </body>
For more details, see the references here:
https://developer.chrome.com/multidevice/android/intents
https://developers.google.com/app-indexing/webmasters/server
https://developer.android.com/training/app-indexing/enabling-app-indexing.html#webpages
And here's a deep link testing tool for Android: https://developers.google.com/app-indexing/webmasters/test.html
Hope that helps.
1 Since the old AOSP browser was replaced by chromium, this is now the default way to handle deep links for recent Android versions. Nonetheless, Android still requires a conditional soltion, because older OS versions still use the AOSP browser.
I have created a Javascript plugin, which supports most of the modern browsers on mobile. But it requires to have deep linking landing pages to be hosted on cross domain(different than universal link url) to work on ios9 Facebook using universal linking. There is also different way to get that working on the Facebook iOS9 using Facebook SDK. I am sharing this if anyone might find this helpful. Currently it does not fallback option, but if falls back to the App Store.
https://github.com/prabeengiri/DeepLinkingToNativeApp
I am Using this Code to for deeplinking.
If the app is installed the app will open up..
If the app is not installed then this remains as it is..
If you wish to add any other condition for app no install then just uncomment the setTimeout code .
<script>
var deeplinking_url = scootsy://vendor/1;
$(document).ready(function(){
call_me_new(deeplinking_url);
});
var call_me_new = function(deeplinking_url){
if(deeplinking_url!=''){
var fallbackUrl ='http://scootsy.com/';
var iframe = document.createElement("iframe");
var nativeSchemaUrl = deeplinking_url;
console.log(nativeSchemaUrl);
iframe.id = "app_call_frame";
iframe.style.border = "none";
iframe.style.width = "1px";
iframe.style.height = "1px";
iframe.onload = function () {
document.location = nativeSchemaUrl;
};
iframe.src = nativeSchemaUrl; //iOS app schema url
window.onload = function(){
document.body.appendChild(iframe);
}
//IF the App is not install then it will remain on the same page.If you wish to send the use to other page then uncomment the below code and send a time interval for the redirect.
/*
setTimeout(function(){
console.log('Iframe Removed...');
document.getElementById("app_call_frame").remove();
window.location = fallbackUrl; //fallback url
},5000);*/
}
};
</script>
setTimeout(function () { if (document.hasFocus()) { window.location = 'URL WILL BEHERE';} }, 2000);
window.location = 'app://';
Need to check document.hasFocus() here because if app is open then playstore url is also open in browser
I also had similar issue, there is a possible alternative for this. If the app is not installed on user's device we can redirect that to some other url.To know more about it Check Here
Example:
Take a QR code
In my case its working fine in opera and chrome browser my deeplink url is
"intent://contentUrl + #Intent;scheme=" +envHost +;package="+envHost+";end";
For other browser create iframe and append the url.
Note -: iframe url append having issue with old device and in firefox its opening app dialog .
I want my website to redirect to a specific app in the Google Play Market if it is opened on an android device. I followed the instructions on http://developer.android.com/guide/publishing/publishing.html:
"Display the details screen for a specific application: http://play.google.com/store/apps/details?id=<package_name>".
Works great with a link the user is actively clicking on:
Download app
But if I am detecting the device with javascript and trying to redirect the browser automatically changes the http://... to https://... and the user is redirected to the Google Play website instead of the Google Play app on the phone.
if(navigator.userAgent.toLowerCase().indexOf("android") > -1) {
if(confirm("Download app?")) {
window.location.href= "http://play.google.com/store/apps/details?id=<package_name>";
}
}
Is there any way to change this behavior, my test device is a Samsung Galaxy with android 2.3.3?
This seems to work. The redirect opens the Google Play app while using the default browser, but translates the link to https:// play.google... when using chrome
if(navigator.userAgent.toLowerCase().indexOf("android") > -1) {
if(confirm("Download app?")) {
window.location.href= "market://details?id=<packagename>";
}
}
If you want to redirect to Google Play app try doing it from the server.
Client side attempts will not work.
PHP example
header("Location: market://details?id=com.your.app");
If the accepted answer does not work or fails to open in Chrome with this error
ERROR: ERR_UNKNOWN_URL_SCHEME
Change the window.location.href to window.location like this
if(navigator.userAgent.toLowerCase().indexOf("android") > -1) {
if(confirm("Download app?")) {
window.location= "market://details?id=<packagename>";
}
}
I am going to add my website to the facebook as an application. Facebook do not allow 3 rd party ads so i have to remove them. I want to remove ads for only facebook visitors. So i want to understand whether page is being called under facebook as an iframe or not. How can i do that with javascript ? Thank you.
I can also use jquery.
asp.net 4.0
The following detects if your page is viewed in an iframe:
if (window.location != window.parent.location){
//you are in an iframe
}
else {
//you are NOT in an iframe
}
[EDIT]
If you want also to specify that the iframe is in facebook then you could try this:
if(window.name != "") {
//We are on Facebook
}
else
{
//We are just in the normal browser window
}
I haven't tested this, just came across a few weeks ago here