2

My issue is the current firebase AUTH is kind of blind to what kind of user is getting created, I want to create a cloud function that can handle 2 different types of user or at least disable the creation of the other type of user (meaning if the user is not an admin then it will be created only from the front-end and and the cloud function wont be ran only if the user is admin ) any idea how to achieve this kind of behavior and make the .onCreate() method distinguish between the 2 different types of users getting created ?

export const accountCreate = functions.auth.user().onCreate((user) => {
  const expiresIn = 60; // test 1h   //172800  === 48h
  const createdAt = admin.firestore.Timestamp.now().toDate();
  createdAt.setSeconds(createdAt.getSeconds() + expiresIn);

  const payload = {
    user: 'Admin', // later dynamic
    verifiedEmail: false,
    sharedId: user.uid,
    createdAt: admin.firestore.Timestamp.now(), //admin.firestore.FieldValue.serverTimestamp(),
    premiumUntill: admin.firestore.Timestamp.fromDate(createdAt), //.toMillis() + 86400000, // +24h days //
    clients: [],
    unit: '',
  };

  return db
    .collection('Data')
    .doc(user.uid)
    .set(payload)
    .catch((err: any) => {
      console.log(err);
    });
});
Dharmaraj
  • 47,845
  • 8
  • 52
  • 84
Richardson
  • 1,804
  • 10
  • 38
  • How do you check whether a user would be Admin or no? You can just call a callable function but there must be some additional check to verify if user is meant to be an admin. – Dharmaraj May 08 '22 at 07:21

1 Answers1

1

The .onCreate() will trigger the function for every user created in Firebase Auth and there's no way to conditionally trigger it. If you do not want to trigger the function every time then you can just use a callable function instead.

const createUser = async () => {
  const { user } = await createUserWithEmailAndPassword(auth, email, password);
  
  if (userShouldBeAdmin()) {
    // call the cloud function to update document/custom claims
    const updateUserType = httpsCallable(functions, 'updateUserType');
    const res = await updateUserType({ ...data })
  }
}
export const updateUserType = functions.https.onCall((data, context) => {
  const { uid } = context.auth; 
  // When using onRequest() functions, you must manually verify user's ID Token

  // TODO: Check if user is meant to be public as per your logic
  // if yes, update relevant documents and claims
  // else return an error.

  return;
});

Also, you cannot pass any custom parameter the onCreate() but you can do so using callable functions if needed.

Dharmaraj
  • 47,845
  • 8
  • 52
  • 84
  • is this callable function more secure and abuse proof that onReuest ? what is the difference between the two ? – Richardson May 08 '22 at 07:32
  • 1
    @stop-error the `onCall()` are easier to call and they also authenticate user and provide caller's info in the function context. Checkout [this answer](https://stackoverflow.com/questions/51066434/firebase-cloud-functions-difference-between-onrequest-and-oncall) for detailed explanation. Also irrespective of which function you use, do ensure that you verify that user is meant to be an admin. I've updated the answer with the same – Dharmaraj May 08 '22 at 07:40