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

When crating a user, beforeSignIn may be called multiple times with uids not corresponding to firebase users #1511

Open
bragma opened this issue Jan 8, 2024 · 3 comments
Labels
tracked internally Issues that are tracked internally, even though the issue is closed type: bug

Comments

@bragma
Copy link

bragma commented Jan 8, 2024

[REQUIRED] Version info

node:

v21.5.0

firebase-functions:

v1

firebase-tools:

13.0.2

[REQUIRED] Test case

Sample Firebase Auth beforeSignIn function code:

"use strict";

const functions = require("firebase-functions");
const admin = require("firebase-admin");

admin.initializeApp();

exports.beforeSignIn = functions.region("europe-west1").auth.user().beforeSignIn(async (user, context) => {
  console.log(`SignIn user id ${user.uid}`);
});

exports.beforeCreate = functions.region("europe-west1").auth.user().beforeCreate(async (user, context) => {
  console.log(`Create user id ${user.uid}`);
});

[REQUIRED] Steps to reproduce

Create a Firebase Auth service and add blocking "beforeCreate" and "beforeSignIn" functions. Issue multiple createUserWithEmailAndPassword requests with the same email in parallel.

[REQUIRED] Expected behavior

  1. Even if multiple createUserWithEmailAndPassword calls are issued with the same email, only a single user is created with the specified email
  2. When creating a new user, beforeSignIn is called once, with the uid of the user created in point 1

[REQUIRED] Actual behavior

  1. Even if multiple createUserWithEmailAndPassword calls are issued with the same email, only a single user is created with the specified email
  2. beforeSignIn is called multiple times, with different uids. Only one of the uids matches the uid of the user created in point 1. As a side note, beforeCreate is called multiple times too but this is expected.

Background info: when a user is created via firebase auth, I also need to create an account on my backend. This is done with an HTTP call to my API issued in the beforeCreate blocking function. Due to the way Firebase Auth UI works on iOS, it may happen that a user taps the "create" button multiple times while previous creation request has not returend yet. This causes the SDK to call createUserWithEmailAndPassword multiple times and beforeCreate is called multiple times for the same email/user creation request. The result is that a single user is created on firebase auth, but multiple users are created in my backend (since they have different firebase uid).

So I decided to move the creation of the user in the backend from beforeCreate to beforeSignIn blocking functions. I expected that "beforeCreate" might be called multiple times, since as the name implies the user does not exist yet in firebase when it is called. But I was expecting "beforeSignIn" to be called only once, since documentation states that the flow is:

  1. beforeCreate is called
  2. user is created in firebase
  3. beforeSignIn is called

Problem is that beforeSignIn is called for all "tentative" uids. Only one of those ids actually matches the user created in firebase.

Were you able to successfully deploy your functions?

Yes, problem is not deploy related.

@google-oss-bot
Copy link
Collaborator

I found a few problems with this issue:

  • I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
  • This issue does not seem to follow the issue template. Make sure you provide all the required information.

@Berlioz
Copy link
Contributor

Berlioz commented Jan 12, 2024

Typically, the correct approach is to prevent multiple create attempts from being made, by disabling the button after the first press or something. It seems like you're using FirebaseUI though, and it does look like there's an outstanding bug for this behavior in that repository (firebase/FirebaseUI-iOS#1169) so it might be on that repository's maintainers to fix this one. We've raised it internally in the hopes of getting some eyeballs on the issue.

@bragma
Copy link
Author

bragma commented Jan 24, 2024

I agree that the UI button should be blocked, but a client side solution for a problem that shows up in the server is often a clunky solution. So, point n.1 UI should be fixed. But what puzzles me is why the beforeSignIn function is called with a user that will never be created. I was kind of expecting this for a beforeCreate, but not at signin, considering that on Firebase Auth a single user is created without duplicates.

Let me reiterate on this: if the UI button is pressed multiple times (ex: 3 times):

  1. 3 different "tentative users" will be created
  2. beforeCreate will be called 3 times, one for each different user
  3. Only one of the 3 different users will actually be stored and accepted for Firebase Auth
  4. afterSignIn is called 3 times with the 3 tentative users, knowing from step 3 that only 1 of those will actually be a valid user. 2 signin of those will actually fail.

Considering this is a signin, 4 does not make any sense.

@colerogers colerogers added type: bug tracked internally Issues that are tracked internally, even though the issue is closed and removed needs-triage labels Jan 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tracked internally Issues that are tracked internally, even though the issue is closed type: bug
Projects
None yet
Development

No branches or pull requests

4 participants