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;
});
}