firebase / firebase-js-sdk

Firebase Javascript SDK
https://firebase.google.com/docs/web/setup
Other
4.83k stars 891 forks source link

Google as an Auth provider doesn't work on iOS saved to homescreen #77

Closed Haroenv closed 4 years ago

Haroenv commented 7 years ago

[REQUIRED] Describe your environment

[REQUIRED] Describe the problem

Steps to reproduce:

  1. Save the app on the homescreen on iOS
  2. make a redirect or popup login with google Auth provider
  3. if redirect:
    • webview is not a "valid user agent"
  4. if popup:
    • gets stuck in Safari about:blank, doesn't open the app again to pass on the token

Relevant Code:

import firebase from "firebase";

const config = {
//...
};

firebase.initializeApp(config);

const googleAuthProvider = new firebaseAuth.GoogleAuthProvider();

firebase.auth().signInWithRedirect(googleAuthProvider);
// or
firebase.auth().signInWithRedirect(googleAuthProvider);
socceroos commented 6 years ago

@johnozbay I was more thinking with the solution above that you open a popup from your PWA that is the login page (happening in Safari). OAuth occurs in Safari login page and upon completion the login page calls window.opener.postMessage with the token. This is received by the PWA which then does token login. Technically you'd be logging them in twice, but it would be less UX hassle.

So: PWA -> open popup Login.html -> Login.html does OAuth flow in Safari -> Login.html does window.opener.postMessage with the token -> PWA receives message, closes popup and does token login.

Maybe I'm missing something?

johnozbay commented 6 years ago

@socceroos iOS reloads pinned home screen applications when you navigate away and back, losing its state. (and completely restarts them) As far as I know, pinned applications in iOS are 100% air-gapped with no way to pass data between pinned application & Safari reliably across all versions of iOS and Safari. (I'd love to be proven wrong here) So, sadly postMessage wouldn't be able to communicate back. (PWA wouldn't receive the message)

kirillgroshkov commented 6 years ago

Same issue for me. Cannot authorize user with github auth in iOS homescreen app (PWA).

abelson commented 6 years ago

@johnozbay can you kindly share your code to the second solution? Thanks

johnozbay commented 6 years ago

@abelson I'm afraid not. It's deeply integrated into the login flow for a client project that supports multiple odd providers, so it would require me to rewrite a distilled version of this from scratch.

If there's any specific part that you're stuck with I'd be happy to help clarify as much as I can.

turadg commented 6 years ago

Fixing this may depend on https://bugs.webkit.org/show_bug.cgi?id=185400

tomodian commented 6 years ago

Curious that iOS Safari on iPhone (11.4) doesn't work, however iPad (11.2.5) works without any problem.

socceroos commented 6 years ago

@tomodian The change in browser context handling on iOS was introduced in 11.3. 11.2 is unaffected. 👍

jorge-valvert commented 6 years ago

I´m assuming that you have a "manifest" meta tag to reference manifest.json file.

I suggest to do this workaround, that works perfect in ios safari web app:

https://stackoverflow.com/a/52286655/8390589

danielruiz7 commented 6 years ago

@jorge-valvert is right. Tested in my own project and social login is working now. Thanks for sharing.

aSegatto commented 6 years ago

@jorge-valvert solution works on iOS also for us, breaks Chrome so it still needs some imprevements. Thanks !

danielruiz7 commented 6 years ago

@aSegatto for me is working both. What I did was adding two link tags for the same manifest:

When page is loaded I check if it's on iOS and do the following in order to avoid safari to read the rel="manifest":

document.querySelector('link[rel="manifest"]').setAttribute("rel", "no-on-ios");

I'm not sure if it's necessary though.

This way Chrome is able to read the manifest via rel="manifest" and pwacompat.js is able to prepare the meta tags for iOS using rel="pwa-setup".

jvitor83 commented 5 years ago

With:

The https://github.com/GoogleChromeLabs/pwacompat/blob/master/pwacompat.js modified at https://github.com/GoogleChromeLabs/pwacompat/blob/master/pwacompat.js#L36 to const manifestEl = document.head.querySelector('link[rel="pwa-setup"]');

and this configuration at index.html:

  <link rel="manifest" href="manifest.json">
  <link rel="pwa-setup" href="manifest.json">
  <script src="pwacompat.js"></script>
  <script>
   var iOS = !!navigator.platform && /iPhone|iPod/.test(navigator.platform);
   if(iOS) {
      document.querySelector('link[rel="manifest"]').setAttribute("rel", "no-on-ios");
   }
  </script>

it works!

rodolfocop commented 5 years ago

We are having a problem similar to this in our application. If you want you can use the following code above that my friend @jvitor83 created. Thank you for your help @danielruiz7 .

theigl commented 5 years ago

This works for me but without the manifest all the internal links in my application open a browser window. Did anyone run into this issue and resolve it?

rodolfocop commented 5 years ago

@theigl You have tried using code the @jvitor83 ? I am saying because this problem not occur to us.

satoshi-m8a commented 5 years ago

Is this article helpful? https://medium.com/@jonnykalambay/progressive-web-apps-with-oauth-dont-repeat-my-mistake-16a4063ce113

robert-king commented 5 years ago

@jvitor83 the modified pwacompat.js solution stopped working for me recently. Was working a couple of weeks ago. Not sure what changed, perhaps it's because I updated to the latest version of angular and firebase. Is anyone else having issues with pwacompat? I'm just going to not use google login for PWAs, seems like PWAs aren't there yet.

joewoodhouse commented 5 years ago

@jvitor83 thanks for your solution, a few comments/thoughts

Looking at the pwacompat.js script, the const manifestEl is just used to get the URL of the manifest.json file. So if you're going to modify the script, you may as well just hardcode the path to the manifest file - this would remove the need for having the 2 <link> tags I think? i.e.

 <link rel="manifest" href="manifest.json">
 <script src="pwacompat.js"></script>
 <script>
   var iOS = !!navigator.platform && /iPhone|iPod|iPad/.test(navigator.platform) && !window.MSStream;
   if(iOS) {
      document.querySelector('link[rel="manifest"]').setAttribute("rel", "no-on-ios");
   }
 </script>
  // pwacompat.js around line 36
  function setup() {
    const manifestHref = 'manifest.json';
    const hrefFactory = buildHrefFactory([manifestHref, window.location]);
    ...

Note I also tweaked the iOS detection to include iPads and to disregard some versions of IE that tried to be iPhones.

Whilst I'm pleased that the fix is getting my app working, has anyone actually worked out how/why this fixes the OAuth issue? From reading the script, all it does is read your manifest.json file and then add some meta tags to the page accordingly (plus some other bits with splashes and icons)- I'd be interested to know which of those tags actually makes the difference, then potentially I could remove the use of the script. Anyone have any ideas?

gmjelle commented 5 years ago

Did this "fix" stop working?

When I save the PWA to homescreen and try to log in, it opens Safari, I go through the oauth2 process and am redirected to the app in the Safari browser - not in the installed PWA. When I go back to the installed PWA it's still not authed.

Authentication part:

    // this.auth is refering to firebase auth
    doSignInWithFacebook = () =>
        this.auth.signInWithRedirect(this.facebookProvider)
    doSignInWithGoogle= () =>
        this.auth.signInWithRedirect(this.googleProvider)

PWA Compat Hack HTML:

  <link rel="pwa-setup" href="manifest.json">
 <script src="./pwacompat.js"></script>
    <script >
     var iOS = !!navigator.platform && /iPhone|iPod|iPad/.test(navigator.platform) && !window.MSStream;
   if(iOS) {
      document.querySelector('link[rel="manifest"]').setAttribute("rel", "no-on-ios");
   }
    </script>

PWA Compat Hack, pwacompat.js ~line 36 const manifestEl = document.head.querySelector('link[rel="pwa-setup"]');

Tested on physical iPhone X with iOS 12.1.2. Tested in Xcode simulator on various simulators.

aSegatto commented 5 years ago

We are currently using the solution proposed incomment and it's still working.

PutziSan commented 5 years ago

Will Google Auth work with the next release of iOS 12.2? (Mike Hartington's comment on twitter seems to suggest this)

powerspowers commented 5 years ago

I just tried the solution and while it lets you start the login to your google account you cannot complete it if Google decides to send you a text message code to confirm. When you leave to get your code and then come back the page for typing in your code disappears and you have to start the sign in process again. (iOS 12.2 - redirect)

The Facebook login works now with this modification ... although, its not asking for 2-step authentication so who knows what happens if thats enabled.

powerspowers commented 5 years ago

I just tested in iOS 12.3.1 and google login in my web app works correctly. I was able to complete 2 step verification by leaving my web app, picking up the number via text and popping back into my app. It looks like google login on the home screen is fixed! Facebook login works correctly as well.

MeghaB commented 4 years ago

Closed, as the issue has been fixed.