Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Firebase Authentication Fails When Switching Between Two Targets #7341

Open
BosPrusin opened this issue Jan 21, 2021 · 11 comments
Open

Firebase Authentication Fails When Switching Between Two Targets #7341

BosPrusin opened this issue Jan 21, 2021 · 11 comments

Comments

@BosPrusin
Copy link

BosPrusin commented Jan 21, 2021

[REQUIRED] Step 1: Describe your environment

  • Xcode version: 11.7
  • Firebase SDK version: 6.31.1
  • Installation method: CocoaPods
  • Firebase Component: Auth, Core, Database, Firestore, Storage

[REQUIRED] Step 2: Describe the problem

When using an iOS project with two targets, both with their own associated GoogleService-Info.,plist files switching between the two targets either on an actual device or a simulator causes authentication to fail.

Steps to reproduce:

What happened? How can we make the problem occur?
This could be a description, log/console output, etc.

In order to reproduce try the following

  1. Setup two different Firebase projects with their own database instance.
  2. Create an iOS project with two targets each with their own GoogleService-Info.plist file
  3. Try to login with a custom token via the Firebase SDK (1st target will work)
  4. Switch to the second target in Xcode.

Observed Behavior:

Authentication will fail now when trying to use a custom token with the new second target.

The error noted in the debug console is as follows:

Error Domain=FIRAuthErrorDomain Code=17000 "The custom token format is incorrect. Please check the documentation." UserInfo={NSLocalizedDescription=The custom token format is incorrect. Please check the documentation., FIRAuthErrorUserInfoNameKey=ERROR_INVALID_CUSTOM_TOKEN}

If you switch back to the first target it will authenticate fine. Also if you are on a simulator and "Reset Content and Settings" the authentication issue will resolve. Likewise if you reset an actual physical device clearing out all content and settings it will resolve for the device as well.

Also in this new state after clearing settings if you choose the second target first it will authenticate fine but when going to the first target it will now fail.

Reference internal bug ID
http://b/177424672

@samtstern
Copy link
Contributor

Assigning to @malcolmdeck who is on call this week.

@malcolmdeck
Copy link

Thanks for the report - I've filed b/178378423 to track this internally. I'll talk to our iOS lead to figure out what the semantics are for multi-app configurations and see if there's anything about custom auth that should/shouldn't work and isn't in this case.

@malcolmdeck
Copy link

Hey there, I have an update for you! It looks like out backend is seeing custom tokens that are missing the signature piece (Custom tokens are of the format {Header}.{Payload}.{Signature}). We also see some valid requests. In order to investigate further, we need to see this reproduced again, but as far as we can tell there's nothing on our end that would be causing the custom token to have an incorrect format.

@BosPrusin
Copy link
Author

BosPrusin commented Feb 9, 2021 via email

@BosPrusin
Copy link
Author

BosPrusin commented Feb 9, 2021 via email

@malcolmdeck
Copy link

First of all, sorry for dropping off the face of the earth.

As for the error message, that appears to be part of FirebaseDatabase's auth management mechanism. I don't know why it would end up triggering anything about a custom token - theoretically, once a user logs in with a custom token, there shouldn't be any other custom token interactions (especially from non-Auth SDKs). Everything else deals with Firebase Auth tokens. It's unclear to me why that piece of code would trigger anything to do with your custom tokens. Rerouting to someone who may know more.

@rosalyntan
Copy link
Member

Hi @BosPrusin -- sorry you're experiencing this issue!

I want to make sure I understand the issue.

Just to be clear after diving into this more on our end, our use of a custom token to login initially does appear to be working or at least responds as such from the API without an error. However I notice in the console log that we are seeing numerous messages being generated in FPersistentConnection complaining about the custom token being invalid and for the wrong project. The line generating the error message is:

FFWarn(@"I-RDB034018", @"Authentication failed: %@ (%@)”, status, responseData);

Is this still after switching targets in Xcode? Or are you seeing a different issue now?

@BosPrusin
Copy link
Author

Yes the issue still occurs when switching between targets in Xcode. What I noticed was that the authentication with the custom token was valid and returned successfully. However the console log was throwing the error I listed above. My suspicion all along has been the cached token used from the first target authentication given our use of persistence.

@rosalyntan
Copy link
Member

Hi @BosPrusin, can you provide some example code of how you are obtaining and sending your custom token? It does seem likely that the custom token for the wrong project is being sent to the backend after you switch targets in Xcode.

@BosPrusin
Copy link
Author

Sure. But again to be clear we are seeing the auth coming back successful which mean the initial login event is working and not a result of an invalid token being sent. It is subsequent calls made by the SDK that I see the error in the log as mentioned.

Here is a snippet of our login:

Auth.auth().signIn(withCustomToken: token) { (user, error) -> Void in
if error != nil {
print(error!)
...

That call is working. It is my belief that in your SDK you have the older token cached and that is the root of the problem. Clearing out the cache by doing a full reset on the device or simulator resolves the issue. In the Firebase documentation it states "If your app uses Firebase Authentication, the Firebase Realtime Database client persists the user's authentication token across app restarts."

When signing in with the above method with a new custom token, which would be the case when running the app with a new target (environment settings) does the SDK clear out the old token being cached?

@katowulf
Copy link

katowulf commented Sep 7, 2021

For seeing if RTDB is doing something interesting with the tokens, you can turn on debug logging, which will tell you everything RTDB is doing. You should be able to see if it's still referencing the old token through the logs. A significant question here is: Does changing the target in XCode have anything to do with production environments or is this a testing environment (there are more options in testing; example remove the app and reinstall, try to delete tokens for the keychain, etc).

If it turns out there is an issue with RTDB caching the data, then it's important to note that RTDB default instance is cached as a singleton or similar under the hood, and reinitializing (calling initializeApp() again) would probably fix any token issues here. But I'm not sure how one purges the old instance effectively to avoid the error about calling initializeApp() twice. That might take some code hunting. I think you could use named apps/multiple project config to work around this:

// Configure an alternative FIRApp after switching environment
FirebaseApp.configure(name: "secondary", options: secondaryOptions)

// Retrieve a previous created named app.
guard let secondary = FirebaseApp.app(name: "secondary")
  else { assert(false, "Could not retrieve secondary app") }


// Retrieve a Real Time Database client configured against a specific app.
let secondaryDb = Database.database(app: secondary)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants