Skip to content

ddx001/ios-problem

Repository files navigation

This is a small Ionic-Angular project to reproduce this issue: ionic-team/capacitor#7631

It consists of a blank Ionic app (created with ionic start) with Firebase Auth added to it. When executed, the app displays a "Sign in anonymously" / "Sign out" button and displays the uid of the logged-in user.

Setup:

  • Create a Firebase project (https://console.firebase.google.com/) and enable Authentication on it. Then, in the "Sign-in method" tab, add the "Anonymous" sign-in provider.
  • Clone the project git clone https://github.com/ddx001/ios-problem.git
  • Configure the project to use Firebase by updating the files in src/environments with your new Firebase project's configuration.
  • Run npm install
  • Run ionic serve
  • Open the app (http://localhost:8100) in a browser and click the "Sign in anonymously" button.

It should Sign in and display the uid of the logged-in user. That's the expected behavior.

Reproduce the bug:

  • Build the app ionic build --prod
  • Copy to iOS npx cap sync ios
  • Open the project in Xcode npx cap open ios
  • Run the project on a device.

Now it doesn't work. That's the bug!

Error messages:

nw_application_id_create_self NECP_CLIENT_ACTION_GET_SIGNED_CLIENT_ID [80: Authentication error]
Failed to resolve host network app id
Warning: -[BETextInput attributedMarkedText] is unimplemented
KeyboardPlugin: resize mode - native
⚡️  Loading app at capacitor://localhost...
⚡️  WebView loaded
⚡️  [log] - heartbeats undefined
⚡️  [log] - heartbeats undefined
⚡️  To Native ->  App addListener 103483311
⚡️  To Native ->  Keyboard getResizeMode 103483312
⚡️  TO JS {"mode":"native"}
Invalidating grant <invalid NS/CF object> failed

Debugging / Fixing:

  • Start the app in Xcode.
  • Open Safari, click on the "Develop" menu and select device.
  • Click on the reload icon in the Safari Web Inspector.

Errors:

[Error] TypeError: undefined is not an object (evaluating 'gapi.iframes.getContext')
[Error] Error: w`capacitor
[Error] Cross-origin redirection to http://developers.google.com/ denied by Cross-Origin Resource Sharing policy: Origin capacitor://localhost is not allowed by Access-Control-Allow-Origin. Status code: 301
[Error] XMLHttpRequest cannot load https://apis.google.com/_/jserror?script=https%3A%2F%2Fapis.google.com%2F_%2Fscs%2Fabc-static%2F_%2Fjs%2Fk%3Dgapi.lb.fr.r1jvixKj4ng.O%2Fm%3Dgapi_iframes%2Frt%3Dj%2Fsv%3D1%2Fd%3D1%2Fed%3D1%2Frs%3DAHpOoo9o9T65AZaaIjldT_tEb7nM0LGeIQ%2Fcb%3Dgapi.loaded_0&error=w%60capacitor&line=147 due to access control checks.
[Error] Failed to load resource: Cross-origin redirection to http://developers.google.com/ denied by Cross-Origin Resource Sharing policy: Origin capacitor://localhost is not allowed by Access-Control-Allow-Origin. Status code: 301 (jserror, line 0)

Cross-origin error:

  plugins: {
    CapacitorHttp: {
      enabled: true
    }
  }
  • Result: the Cross-origin error is gone, we now have:
[Error] TypeError: undefined is not an object (evaluating 'gapi.iframes.getContext')
[Log] native CapacitorHttp.request (#123355916) (user-script:2, line 364)
  [Log] Object (user-script:2, line 371)
    callbackId: "123355916"
    methodName: "request"
    options: {url: "https://apis.google.com/_/jserror?script=https%3A%…2Fcb%3Dgapi.loaded_0&error=w%60capacitor&line=147", method: "POST", data: "trace=%40https%3A%2F%2Fapis.google.com%2F_%2Fscs%2…3Dgapi.loaded_1%3A1%3A14&context.severity=unknown", headers: {Content-Type: "application/x-www-form-urlencoded;charset=utf-8"}, dataType: "json"}
    pluginId: "CapacitorHttp"
    type: "message"
    Prototype Object
[Error] Error: w`capacitor
[Log] result CapacitorHttp.request (#123355916) (user-script:2, line 338)
  [Error] Object
    code: "NSURLErrorDomain"
    errorMessage: "The resource could not be loaded because the App Transport Security policy requires the use of a secure connection."
    message: "The resource could not be loaded because the App Transport Security policy requires the use of a secure connection."
	<key>NSAppTransportSecurity</key>
  <dict>
    <key>NSExceptionDomains</key>
    <dict>
      <key>apis.google.com</key>
      <dict>
        <key>NSIncludesSubdomains</key>
        <true/>
        <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
        <true/>
        <key>NSTemporaryExceptionMinimumTLSVersion</key>
        <string>TLSv1.0</string>
      </dict>
      <key>developers.google.com</key>
      <dict>
        <key>NSIncludesSubdomains</key>
        <true/>
        <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
        <true/>
        <key>NSTemporaryExceptionMinimumTLSVersion</key>
        <string>TLSv1.0</string>
      </dict>
    </dict>
  </dict>
  • The error is gone, but the app still doesn't work.
  • Logs:
[Error] TypeError: undefined is not an object (evaluating 'gapi.iframes.getContext')
[Log] native CapacitorHttp.request (#105958631) (user-script:2, line 364)
  [Log] Object (user-script:2, line 371)
    callbackId: "105958631"
    methodName: "request"
    options: {url: "https://apis.google.com/_/jserror?script=https%3A%…2Fcb%3Dgapi.loaded_0&error=w%60capacitor&line=147", method: "POST", data: "trace=%40https%3A%2F%2Fapis.google.com%2F_%2Fscs%2…3Dgapi.loaded_1%3A1%3A14&context.severity=unknown", headers: {Content-Type: "application/x-www-form-urlencoded;charset=utf-8"}, dataType: "json"}
    pluginId: "CapacitorHttp"
    type: "message"
    Prototype Object
[Error] Error: w`capacitor
[Log] result CapacitorHttp.request (#105958631) (user-script:2, line 338)
  [Log] Object (user-script:2, line 349)
    data: "<!doctype html>↵<html ↵      lang=\"en\"↵      dir=\"ltr\">↵  <head>↵    <meta name=\"google-signin-client-id…"
    headers: {cache-control: "no-cache, must-revalidate", expires: "0", content-security-policy: "base-uri 'self'; object-src 'none'; script-src 'st…ort-uri https://csp.withgoogle.com/csp/devsite/v2", x-cloud-trace-context: "95297de33fb653b36c481ac2fcd4b4b3", alt-svc: "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000", …}
    status: 200
    url: "https://developers.google.com/"
    Prototype Object
  • Added console logging to firebase-auth.service.ts:
  • Result in 'ionic serve' mode (load then click button):
***** Calling getAuth(initializeApp(...))
***** getAuth(initializeApp(...)) call complete
***** Calling onAuthStateChanged()
***** onAuthStateChanged() call complete
***** onAuthStateChanged() callback null
***** Calling signInAnonymously()
***** onAuthStateChanged() callback _UserImpl {providerId: 'firebase' ...
***** signInAnonymously() call complete
***** Calling signOut()
***** onAuthStateChanged() callback null
***** signOut() call complete
  • Result in iOS (same actions - load then click button):
***** Calling getAuth(initializeApp(...))
***** getAuth(initializeApp(...)) call complete
***** Calling onAuthStateChanged()
***** onAuthStateChanged() call complete
!!! NO CALLBACK, NO ERROR !!!
***** Calling signInAnonymously()
!!! NOTHING HAPPENS, CALL DOESN'T COMPLETE, NO AUTH STATE CHANGED CALLBACK, NO ERRORS !!!

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published