We have an android website which opens in webview(ie from app) and also in web browser.
In both cases we have to show different behaviour. Is there any way to distinguish whether the request is from app webview(which internally opens the application on native browser) or direct browser request.
We cannot depend on user agent as we cannot update client side.
I want to do something like this:
if(webview)
{}
else if(browser)
{}
Its a high priority issue, so anybody having any clue to resolve this, please post ASAP!
Set a user Agent String in Webview and get it in your code
yourWebView.getSettings().setUserAgentString("Some user agent String to identify");
See this answer it explains how to do it.
if(window._cordovaNative) {
// its a web view
} else {
// its a web browser
}
All http requests sent through a webview have the header bellow present. You can use this to detect where you got the request from
X-Requested-With: the.app.packageName
Related
This is only happening on IOS, on android I'm getting expected behavior.
I have this property on my web view from react-native-webview
onNavigationStateChange={(e) => {
if (e?.url.includes(TOKEN_QUERY_PARAM)) {
let startIndex = e.url.indexOf(TOKEN_QUERY_PARAM);
let token = e.url.substring(startIndex + TOKEN_QUERY_PARAM.length);
authorize(token);
}
}}
As you can see, the webview will send me a link with a token that I can then send to my authorize function to get my user signed into the app. This works the first time the app is used but then begins caching the same call/response if you do it again. Its working as it should on android, but on ios the authorize function is returning the same information from the last time it was called.
Has anyone experienced anything like this? I tried setting all the different cache properties on the webview to be false and it still doesnt work. Any ideas??
I have implemented login using ChromeCustomTabsBrowser. After successful login, if app's Open Supported links setting is set to "Ask evety time" instead of "Open in this app", response is not getting back to the app and showing 404 screen as attached in screen.
Interesting - looks like you are using an https scheme for redirects and here is how we'd like the technology to work:
You are automatically deep linked back to your app when a login response is received over the https URL.
However, in practice I believe this is what happens:
Almost all mobile browsers try to run an internet hosted web page instead
A claimed https scheme solution is very hard to achieve and rarely used in practice today - more of an aspiration than a reality? But I believe it would need to work like this:
Capture the response on the internet web page which runs on your mobile device
Then deep link back to the app
A similar approach is used by a sample internet web page of mine - do a view source to see the logic
If it helps I have a demo Android sample that instead uses the more mainstream option of private URI schemes - though I may update it to claimed https schemes one of these days.
Code
Explanatory Articles
Even getting this form of Chrome Custom Tab based login working was a struggle, and my posts have some lessons learned that may be useful.
FINAL EDIT
This was a bug. After filing the report it was addressed.
EDIT
I am trying to get user id in a webview of my facebook messenger bot. It works fine on mobile, yet fails on desktop (web). This should not be the case.
Messenger 2.1 release statement gives the following quote:
Desktop support for Extensions SDK: This new feature will extend functionality across mobile and web, creating a consistent experience across devices. Now, features like user ID and sharing that used to only be accessible on mobile will be available on desktop as well. This also provides developers with an easier way to test and debug when implementing webview and chat extensions.
There are two ways to get the user id with messenger extensions: getUserId() and getContext(). The docs state that getUserId() is not available on desktop, but make no mention of getContext().
Howevew, there is a bug report that states that getContext() call is not yet available on desktop.
The docs mention no other ways of getting user id. How is one supposed to do that?
As a kicker, if you read the original question, you will see that getContext() actually does work on desktop (web), but only if the webview is opened through a link sent directly by the bot.
ORIGINAL
I am working on a Facebook (messenger) bot using webview.
Now the most basic of all tasks is to get the userId.
This is where I hit a big problem. Having investigated it thoroughly, below I present cases and results.
case 1: my app sends me a generic template with a web_url button (that opens the webview) and a share button.
Everything works great. I get the user id.
case 2: I click share from the message in case 1, and share it with myself and my app.
from either message thread (I to myself, or the I to app) getContext() call return error 2018166 Permission not valid to call the SDK API. and askPermission() returns 2018154 Messenger Extensions unexpected error.
case 3: I click share from inside the webview using beginShareFlow() and share with myself and the bot.
same as case 2
case 4: here's the kicker.
activating the webview from case 2 or case 3 from Android, works and gives me the user id.
case 5: sharing to a friend who has interacted with the app before.
When that friend activates the webview, from desktop it fails, from android works.
case 6: sharing to a friend who has not interacted with the bot.
on desktop doesn't work (sharing by button or through beginShareFlow()), it works!
So, after writing all of this out, the pattern is:
on android, webview sharing works as expected: I can get the user id whether they have interacted with the bot befor or not.
on desktop, the only time the webview provides the user id, is when the message with the webview link was sent by the bot. Once it is shared by a user, the webview still opens, but does not provide context.
Just to clarify. I get the user id by using getContext, and not by getUserId which the docs specifically say doesn't work on desktop.
Is there anything I can do about this? I would like my bot's webviews to work both on desktop and mobile.
I can think of a workaround, but it's far from ideal
EDIT 2
As requested, the payload for sharing within webview is:
{
"attachment":{
"type":"template",
"payload":{
"template_type":"generic",
"elements": [{
"title":"Testing webview",
"default_action":{
"type":"web_url",
"webview_height_ratio": "full",
"messenger_extensions": true,
"url":"https://plenty.life/webview"
},
"buttons":[{
"type":"web_url",
"webview_height_ratio": "full",
"messenger_extensions": true,
"url":"https://plenty.life/webview",
"title":"Test"
}]
}]
}
}
}
Try this...
<script>
window.extAsyncInit = function() {
// the Messenger Extensions JS SDK is done loading
console.log("using getUserId in",window.name)
MessengerExtensions.getUserID(function success(uids) {
// User ID was successfully obtained.
var psid = uids.psid;
console.log(psid);
document.getElementById("userId").innerText="your User Id Is "+psid;
}, function error(err, errorMessage) {
// Error handling code
console.log("some Error",err,errorMessage)
});
MessengerExtensions.getContext('<appID>',
function success(result){
console.log("success",result)
},
function error(result){
console.log("error",result)
}
);
};
</script>
I'm building an android app with Ionic and cordova.
I have one wordpress website - where is oauth2 plugin installed with some access functions. I want first to get code and later send post to retrieve the token. I tested it in web-browser and it works well:
location.replace('https://xxx/oauth/authorize?response_type=code&client_id=xxx&redirect_uri=http://192.168.0.129:8100/');
Im getting code after client login to my website and its redirecting to my app which is standing on ip 192.168.0.129:8100 with code in url - it wo. But in the android Im usining:
var options = {
clearcache: 'yes',
toolbar: 'no'
};
$cordovaInAppBrowser.open('https://xxx/oauth/authorize?response_type=code&client_id=xxx&redirect_uri=http://192.168.0.129:8100/', '_blank' , options)
.then(function(event) {
}).then(function(){
});
Everything works but not redirection - it cant load my app again. I made some research and mostly people place http://localhost/ or http://localhost/callback to go back to android app but it also doesnt work for me. What is the redirect URL than?? How to get back to the app?
of course 'xxx' are just for example;)
After you have opened the url in the in app browser with $cordovaInAppBrowser , you need to listen to an event, $cordovaInAppBrowser:loadstart as described here, http://ngcordova.com/docs/plugins/inAppBrowser/.
So you can do it in the following way,
$cordovaInAppBrowser.open('https://xxx/oauth/authorize?response_type=code&client_id=xxx&redirect_uri=http://192.168.0.129:8100/', '_blank' , options);
$rootScope.$on('$cordovaInAppBrowser:loadstop', function(e, event) {
// check event for which url loaded. if it loaded the http://192.168.0.129:8100/ with the access token, then handle it there and close the in app browser with, $cordovaInAppBrowser.close();
})
So I've created a simple WebView application that wraps an already existing mobile friendly site and displays it on the device. I've enabled javascript, supported screen orientation changes, etc...
I've run into an issue with the oAuth support though. Accessing the site from the chrome browser on the device, everything runs fine.
If I try to access the site from the app/WebView, it will push me over to the oAuth screen, let me input credentials and everything, but the moment it tries to push me back to the website and log me in, I get this:
Failed to recognize URL query:
https://exittix.com/frontend/login/redirect.html#access_token=******************************&expires_in=********&state=****client_id=******************network*****facebook*****display***popup****callback****_hellojs_agj27sx5****state****oauth_proxy***https***auth-server.herokuapp.com%2Fproxy***scope***basic_profile***email***basic***oauth***version***auth***https***facebook.com%2Foauth***
The * is used to protect data.
So, any ideas why oAuth isn't working inside a JS enabled webview but works fine in the mobile chrome browser for android?
Thanks in advance for your help!
EDIT:
Ok, so I've tracked the error I'm getting back to redirect.html.
This page calls some javascript. If the javascript fails to redirect, then it displays that error I have above instead.
The javascript being called to handle the oAuth is Andrew Dodson's hello.js script.
You can see it HERE.
I've concluded that the second half of the error's url is indeed the unhandled JSON.
Here's what the returned data looks like after I've decoded it from the URL encoded characters:
{"client_id":"************.apps.googleusercontent.com","network":"google","display":"popup","callback":"_hellojs_********","state":"","oauth_proxy":"https://auth-server.herokuapp.com/proxy","scope":["https://www.googleapis.com/auth/userinfo.profile","https://www.googleapis.com/auth/userinfo.email","basic"],"oauth":{"version":2,"auth":"https://accounts.google.com/o/oauth2/auth"}}&access_token=***.*.*****_*********************************************************&token_type=Bearer&expires_in=3600
Any ideas why this isn't getting handled properly in the WebView?