firebase-functions: Auth Trigger doesn't include displayName for email+password registration

Hey there,

so at the firebaseui login flow, I can provide a “first & lastname”, which on the frontend login callback will be available through displayName.

image image

However, when I want to access this data from a firebase cloud function on creation of a user, the displayName property is missing from the payload inside event.data.

exports.saveUserData = functions.auth.user().onCreate(event => {
  const user = event.data; // The Firebase user.
  console.log(event);
  const uid = user.uid;
  const email = user.email; // The email of the user.
  const displayName = user.displayName; // The display name of the user.
  const photoURL = user.photoURL || 'https://firebasestorage.googleapis.com/v0/b/medaku-b583e.appspot.com/o/default_avatar.png?alt=media&token=4cb3410a-8bb4-4b48-be09-a2226f5584ad'; // The display name of the user.
  const [firstname, lastname] = displayName ? displayName.split(' ') : ['Fallback Name, as displayName might be missing', 'lastname'];

  console.log('new user registered: ', user);

  const newUser = {
    uid,
    profile: {
      firstname,
      lastname,
      photoURL,
      email: {
        address: email,
        verified: false,
      },
      createdAt: Date.now(),
    }
  }


  return admin.database().ref(`users/${uid}`).set(newUser);
});

the two console.logs output this data in the functions logs

{ data: 
   { email: 'lala@gmail.com',
     metadata: 
      { createdAt: 2017-08-26T12:59:48.000Z,
        lastSignedInAt: 2017-08-26T12:59:48.000Z },
     uid: 'XYRmB99wkpMZhQeJ84v1DTlj5oF3' },
  eventId: 'ad174ea3-e5d6-4e51-92b8-2b67dafbaf4c',
  eventType: 'providers/firebase.auth/eventTypes/user.create',
  notSupported: {},
  resource: 'projects/memema-lala',
  timestamp: '2017-08-26T12:59:48.535Z',
  params: {} }
new user registered:  { email: 'lala@gmail.com',
  metadata: 
   { createdAt: 2017-08-26T12:59:48.000Z,
     lastSignedInAt: 2017-08-26T12:59:48.000Z },
  uid: 'XYRmB99wkpMZhQeJ84v1DTlj5oF3' }

For the facebook login, the displayName property is available on the frontend callback and the cloud function. It’s just the email flow that is different.

How can I access displayName from the email flow inside my cloud functions?

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 12
  • Comments: 20

Most upvoted comments

@bojeil-google I think the bigger problem is that the displayName field is present in firebaseUI, the user fills it out, but then it’s not available in cloud functions. It’s just very messy code now and the client does too much to work around this. Especially since it has to operate on the user without knowing if it’s already created by cloud functions or not.

cc @bojeil-google

So what’s happening here is that the account’s profile, when it is created through password+email, only contains the email (it’s always the case).

See the createUserWithEmailAndPassword API call. Only takes a password and an email to create the account which means that, when the account is created on Firebase Auth backend, only the email is known and part of the profile.

On the client, Firebase UI Web then updates the profile of the User using a subsequent updateProfile call. You don’t “see” this from your web app because Firebase UI resorts to a “trick” to only fire the onAuthStateChanged of your FirebaseApp instance listener after the profile of the user has been updated. (technically: Firebase UI does the account creation and profile update in a separate Firebase App instance, then, when the user is fully ready it signs-the user in your original FirebaseApp instance)

However, on Cloud Function, the trigger will get called right after the createUserWithEmailAndPassword call, before the profile is updated. This is why you only have the email.

@bojeil-google can comment and/or think about new features we could do to have a better experience on Functions. Ideas that come to mind:

  • Add a profile parameter to the [createUserWithEmailAndPassword API call] so that we create new accounts with a pre-populated profile.
  • Add a Cloud Function functions.auth.user().onProfileUpdated trigger. Although that may not entirely fix the issue @codeofsumit is having but could help work around the issue

@bojeil-google whats currently happening is messier and on top of that, its not documented. It makes no sense for other identity providers to work this way and email+password to have a totally different behavior. Is a fix still under consideration or do we have to live with this? Removes the point of building plug and play solutions.

This is still annoying. Other login methods provide displayName on auth create, but email doesn’t, even though the Auth UI gets the display name the same time as the password.

@bojeil-google Wouldn’t the simplest solution be to also allow triggering Cloud Functions on profile updates? That would also be most directly reflective of the underlying system behavior, where account-creation and initial-profile-population are separate calls.

Modifying every sign in method to take the same profile parameters is messy. In addition, 2 RPC calls are needed for each and they would still result in the early trigger you are seeing. So that would need to be updated. An updateProfile API seems better suited on the user with the existing backend API. This is why it was originally designed that way.

@liujin-google Yeah I personally agree we should support triggering events on user updates.

Yeah it’s annoying because it does not work just for email/password, while other providers are working fine.

My workaround is to

export const createProfile = async userRecord => {
  let user = await admin.auth().getUser(userRecord.uid);
  user = user.toJSON();
  // user.displayName is valid while userRecord.displayName is undefined.