google / cordova-plugin-browsertab

A Cordova plugin that provides an interface to in-app browser tabs that exist on some mobile platforms, such as SFSafariViewController on iOS and CustomTabs on Android.
Apache License 2.0
117 stars 147 forks source link

How to close browser tab? #4

Open chuchuva opened 7 years ago

chuchuva commented 7 years ago

It looks that there is no way to close the browser tab. I think this is required to implement the OAuth flow.

chuchuva commented 7 years ago

I think we need to use dismissViewController method. See http://strawberrycode.com/blog/sfsafariviewcontroller-and-oauth-the-instagram-example/

iainmcgin commented 7 years ago

This isn't something you can reliably do across platforms and browsers. Dismissing the tab isn't required for OAuth, all that matters is that the response is ultimately delivered to the requesting app.

chuchuva commented 7 years ago

Dismissing the tab isn't required for OAuth, all that matters is that the response is ultimately delivered to the requesting app.

True but consider scenario:

  1. Bob opens Cordova mobile app on his iPhone and taps 'Sign in with Google' button. Browser tab opens.
  2. Bob enters his Gmail email and password. He approves requested access to his profile.
  3. Browser tab redirects to custom URL schema. The app receives this request. It cannot respond with HTML (because it is Cordova app). So to Bob it looks like nothing has happened.

Bob is frustrated: to him it looks like the app is not working, even though if he taps 'Done' button he would sign in to the app.

mjwwit commented 7 years ago

I'm looking for a way to achieve this on Android.

My situation is as follows: Android behaves differently than iOS when redirecting to a custom URL schema. iOS handles this redirect in the same webview as the one initiating the OAuth flow. Android, however, opens a new webview within the same app to deal with the redirect. The solution for this seems simple at first, just close the old webview using navigator.app.exitApp();. But when one does that directly after opening a Browser Tab, the entire app exits. You need to wait for the new webview to be loaded before you can safely exit the old webview. As there is no way of directly communicating between these webviews, I'm currently abusing localStorage to achieve this. There is one problem with this approach: the opened Browser Tab will stay open in the background with no way to close it.

Any ideas?

gregor-srdic commented 7 years ago

@mjwwit I believe you need to add <preference name="AndroidLaunchMode" value="singleInstance" /> to your config.xml

mjwwit commented 7 years ago

@gregor-srdic Ok, do you know how to configure this? I've been reading https://cordova.apache.org/docs/en/latest/config_ref/ but I can't find anything that looks like what I need.

washowasho commented 6 years ago

@mjwwit Google achieves closing the extra browser WebView with Firebase OAuth as documented here: https://firebase.google.com/docs/auth/web/cordova

I'm trying to figure out how to do it the same way. However, it's in a different project. https://github.com/firebase/firebase-js-sdk/issues/102 I will post my findings here once it's found.

washowasho commented 6 years ago

@gregor-srdic <preference name="AndroidLaunchMode" value="singleInstance" /> doesn't stop a BrowserTab from opening outside of the app... it only prevents another instance of the app being created when a deep link is entered.

washowasho commented 6 years ago

@gregor-srdic & @mjwwit , we were very close. <preference name="AndroidLaunchMode" value="singleTask" /> stops the new window from opening. And should automatically close (at least it does with custom URL scheme).

mjwwit commented 6 years ago

Looks like @washowasho found the solution. The singleTask launch mode solves the problem of the browser tab staying open on Android. And since the iOS implementation already has a working close() method, I think this whole issue can be closed.

larssn commented 6 years ago

@washowasho Do you have any tips on how to close the browser tab on iOS? Feel like I've tried everything at this point:

None of the above closes the tab on iOS. Pretty much all of them closes the tab on Android.

Hope you have a pointer or two.

washowasho commented 6 years ago

Try this. It works for me using custom URL scheme.

<!DOCTYPE html><html><head><script>function customUrlScheme() { window.location = \"" + customUrlSchemeLinkHere + "\" }</script></head><body onload=\"customUrlScheme()\"></body></html>

larssn commented 6 years ago

Thanks, that did something. But the user is presented with a small popup asking if he wants to open in our app, which, in an OAuth flow, is less than desired.

Anyway thank you for your time, I'll go to plan B, which is use this for Android, and cordova-plugin-safariviewcontroller for iOS.

stephane-segning commented 4 years ago

Hi! Any new about this?

Lopuch commented 4 years ago

Try this. It works for me using custom URL scheme.

<!DOCTYPE html><html><head><script>function customUrlScheme() { window.location = \"" + customUrlSchemeLinkHere + "\" }</script></head><body onload=\"customUrlScheme()\"></body></html>

Washowasho's solution works for me. Here is my working code for ASP.Net Core 3.1. It redirects your request with query string to the same page immediately after the page loads. It means the window.close() works because the location is navigated by javascript.

if(Request.Query.ContainsKey("reload")) { if(Request.Query["reload"]=="false") { return Content("<button onclick=\"window.close();\">Close this tab</button>", "text/html"); } } var queryString = Request.QueryString.Value.Replace("?", ""); return Content("<!DOCTYPE html><html><head><script>function customUrlScheme() { window.location = \"test?reload=false&"+queryString+"\" }</script></head><body onload=\"customUrlScheme()\"></body></html>", "text/html");