public updateExistingAccount()

in src/auth/auth-api-request.ts [1366:1494]


  public updateExistingAccount(uid: string, properties: UpdateRequest): Promise<string> {
    if (!validator.isUid(uid)) {
      return Promise.reject(new FirebaseAuthError(AuthClientErrorCode.INVALID_UID));
    } else if (!validator.isNonNullObject(properties)) {
      return Promise.reject(
        new FirebaseAuthError(
          AuthClientErrorCode.INVALID_ARGUMENT,
          'Properties argument must be a non-null object.',
        ),
      );
    } else if (validator.isNonNullObject(properties.providerToLink)) {
      // TODO(rsgowman): These checks overlap somewhat with
      // validateProviderUserInfo. It may be possible to refactor a bit.
      if (!validator.isNonEmptyString(properties.providerToLink.providerId)) {
        throw new FirebaseAuthError(
          AuthClientErrorCode.INVALID_ARGUMENT,
          'providerToLink.providerId of properties argument must be a non-empty string.');
      }
      if (!validator.isNonEmptyString(properties.providerToLink.uid)) {
        throw new FirebaseAuthError(
          AuthClientErrorCode.INVALID_ARGUMENT,
          'providerToLink.uid of properties argument must be a non-empty string.');
      }
    } else if (typeof properties.providersToUnlink !== 'undefined') {
      if (!validator.isArray(properties.providersToUnlink)) {
        throw new FirebaseAuthError(
          AuthClientErrorCode.INVALID_ARGUMENT,
          'providersToUnlink of properties argument must be an array of strings.');
      }

      properties.providersToUnlink.forEach((providerId) => {
        if (!validator.isNonEmptyString(providerId)) {
          throw new FirebaseAuthError(
            AuthClientErrorCode.INVALID_ARGUMENT,
            'providersToUnlink of properties argument must be an array of strings.');
        }
      });
    }

    // Build the setAccountInfo request.
    const request: any = deepCopy(properties);
    request.localId = uid;
    // For deleting displayName or photoURL, these values must be passed as null.
    // They will be removed from the backend request and an additional parameter
    // deleteAttribute: ['PHOTO_URL', 'DISPLAY_NAME']
    // with an array of the parameter names to delete will be passed.

    // Parameters that are deletable and their deleteAttribute names.
    // Use client facing names, photoURL instead of photoUrl.
    const deletableParams: {[key: string]: string} = {
      displayName: 'DISPLAY_NAME',
      photoURL: 'PHOTO_URL',
    };
    // Properties to delete if available.
    request.deleteAttribute = [];
    for (const key in deletableParams) {
      if (request[key] === null) {
        // Add property identifier to list of attributes to delete.
        request.deleteAttribute.push(deletableParams[key]);
        // Remove property from request.
        delete request[key];
      }
    }
    if (request.deleteAttribute.length === 0) {
      delete request.deleteAttribute;
    }

    // For deleting phoneNumber, this value must be passed as null.
    // It will be removed from the backend request and an additional parameter
    // deleteProvider: ['phone'] with an array of providerIds (phone in this case),
    // will be passed.
    if (request.phoneNumber === null) {
      request.deleteProvider ? request.deleteProvider.push('phone') : request.deleteProvider = ['phone'];
      delete request.phoneNumber;
    }

    if (typeof(request.providerToLink) !== 'undefined') {
      request.linkProviderUserInfo = deepCopy(request.providerToLink);
      delete request.providerToLink;

      request.linkProviderUserInfo.rawId = request.linkProviderUserInfo.uid;
      delete request.linkProviderUserInfo.uid;
    }

    if (typeof(request.providersToUnlink) !== 'undefined') {
      if (!validator.isArray(request.deleteProvider)) {
        request.deleteProvider = [];
      }
      request.deleteProvider = request.deleteProvider.concat(request.providersToUnlink);
      delete request.providersToUnlink;
    }

    // Rewrite photoURL to photoUrl.
    if (typeof request.photoURL !== 'undefined') {
      request.photoUrl = request.photoURL;
      delete request.photoURL;
    }
    // Rewrite disabled to disableUser.
    if (typeof request.disabled !== 'undefined') {
      request.disableUser = request.disabled;
      delete request.disabled;
    }
    // Construct mfa related user data.
    if (validator.isNonNullObject(request.multiFactor)) {
      if (request.multiFactor.enrolledFactors === null) {
        // Remove all second factors.
        request.mfa = {};
      } else if (validator.isArray(request.multiFactor.enrolledFactors)) {
        request.mfa = {
          enrollments: [],
        };
        try {
          request.multiFactor.enrolledFactors.forEach((multiFactorInfo: any) => {
            request.mfa.enrollments.push(convertMultiFactorInfoToServerFormat(multiFactorInfo));
          });
        } catch (e) {
          return Promise.reject(e);
        }
        if (request.mfa.enrollments.length === 0) {
          delete request.mfa.enrollments;
        }
      }
      delete request.multiFactor;
    }
    return this.invokeRequestHandler(this.getAuthUrlBuilder(), FIREBASE_AUTH_SET_ACCOUNT_INFO, request)
      .then((response: any) => {
        return response.localId as string;
      });
  }