Create users with email an phone provider using Admin Firebase - node.js

How can one create a user with phone number and email as providers in Firebase?
The code presented only sets up the phone number as being the only provider.
admin.auth().createUser({
uid: email,
email: email,
emailVerified: true,
phoneNumber: checkMobileTel(mobileTel)
})
.then(function(userRecord: { uid: any; }) {
// See the UserRecord reference doc for the contents of userRecord.
console.log('Successfully created new user:', userRecord.uid);
})
.catch(function(error: any) {
console.log('Error creating new user:', error);
});

I think you are forgetting to add the password field. I hope I could help, happy coding!
password string The user's raw, unhashed password. Must be at least six characters long.

Related

Is there a way to tell if a user is registered with phone number or email & password on Firebase Auth

I am building a React App with Firebase back end.
I have two types of users, Admin and Standard users. The admins are created by a Super Admin using email and password and their phone numbers is set to their profile. The Standard user registers using phone number. I would like to send a different registration success SMS for the Admin and the standard user using Firebase cloud functions with the onCreate auth trigger.
Is there a way to tell which user was created through Admin SDK and which one registered through phone Auth.
My create Admin function is as below.
exports.addAdmin= functions.https.onCall((data, context) => {
return admin.auth().createUser({
email: data.email,
password: data.password,
displayName: data.name,
phoneNumber: data.phone,
disabled: false,
emailVerified: true
})
});
You can check if email and phoneNumber are defined in user object of onCreate() function like this:
export const onUserCreate = auth.user().onCreate(async (user) => {
if (user.phoneNumber) {
// User has phone number
}
if (user.email) {
// User has email
}
});
If both admin created and standard users can have email-password auth setup and you want check if they were created by a super admin or no, then you'll have to store the source in a database or custom claims. Try:
export const addAdmin = https.onCall(async (data, context) => {
const user = await getAuth().createUser({
email: "dharmaraj.r244#gmail.com",
password: "data.password",
});
// Add 'source' custom claim
await getAuth().setCustomUserClaims(user.uid, {
source: "admin",
});
return 'User created';
});
export const onUserCreate = auth.user().onCreate(async (user) => {
const { customClaims } = await getAuth().getUser(user.uid);
if (customClaims.source === "admin") {
console.log("User created by super admin")
}
return null;
});

How to unlink Email from Firebase using Firebase Admin Node JS SDK

I'm trying to unlink Email to the current user that has a Phone Number and Email already linked to it.
here what I do :
admin.auth().updateUser("user uid", {
email: null,
password: null,
})
.then(function(userRecord) {
// See the UserRecord reference doc for the contents of userRecord.
console.log('Successfully updated user', userRecord.toJSON());
})
.catch(function(error) {
console.log('Error removing email:', error);
});
but it was returning error The email address is improperly formatted.
for some reason, only when I remove the email this happen, when i do the same for phone its working :
admin.auth().updateUser("user uid", {
phoneNumber: null,
})
.then(function(userRecord) {
// See the UserRecord reference doc for the contents of userRecord.
console.log('Successfully updated user', userRecord.toJSON());
})
.catch(function(error) {
console.log('Error removing phone number:', error);
});
The above code works, the phone is removed perfectly. but only when I do this to Email occurring error.
Is there something I miss?
UpdateRequest#email must be undefined or a valid email.
UpdateRequest#password must be undefined or an unhashed password.
You may be able to use:
admin.auth().updateUser("user uid", {
email: undefined,
password: undefined,
})
But you are often better off unlinking the EmailAuthProvider credential on the client.
firebase.auth().currentUser
.unlink(firebase.auth.EmailAuthProvider.PROVIDER_ID);
You can unlink providers with the admin sdk using the providersToUnlink
await auth.updateUser(user.uid, {
providersToUnlink: ['password'],
})

How to change display name in firebase cloud functions?

I am trying to build a firebase cloud function to change a display name.
I know that i can do it easily in android, but since every time i change the display name i need to update all user records and since there isn't seem to be a way to get notified in firebase function when display name has changed (please correct me if i am wrong), i am planning to make the change in firebase and on the same time make the records update.
This is how i started...
exports.changeDisplayName = functions.https.onCall((data,context) => {
console.log(`User ${context.auth.uid} has requested to change its display name`);
//If user not authenitacted, throw an error
if (!(context.auth && context.auth.token && (context.auth.token.firebase.sign_in_provider === 'phone'))) {
if (!context.auth) {
console.log(`User ${context.auth.uid} without auth`);
}
if (!context.auth.token) {
console.log(`User ${context.auth.uid} without token`);
}
if (!context.auth.token.phoneNumber) {
console.log(`User ${context.auth.uid} without phone number (${context.auth.token.firebase.sign_in_provider})`);
}
throw new functions.https.HttpsError(
'permission-denied',
'Must be an authenticated user with cellphone to change display name'
);
}
// Change display display name from data
// update firebase contacts
});
To update a user's name from Cloud Functions, you'll be using the Firebase Admin SDK for Node.js users. Through that, you can update any properties of a user profile with something like this:
admin.auth().updateUser(uid, {
email: 'modifiedUser#example.com',
phoneNumber: '+11234567890',
emailVerified: true,
password: 'newPassword',
displayName: 'Jane Doe',
photoURL: 'http://www.example.com/12345678/photo.png',
disabled: true
})
.then(function(userRecord) {
// See the UserRecord reference doc for the contents of userRecord.
console.log('Successfully updated user', userRecord.toJSON());
})
.catch(function(error) {
console.log('Error updating user:', error);
});

Error with admin firebase: "admin.auth(...).generatePasswordResetLink is not a function"

I made a email servies via Node.js(nodemailer) and firebase.
When I craete new new user in application, that new user should get welcome email with Link for reseting password.
Now I need to implement firebase admin --generatePasswordResetLink into node.js
In this line of code is problem, errors is that generatePasswordResetLink() is not a function:
admin.auth().generatePasswordResetLink(user.email, actionCodeSettings)
// Create user
async function createUser(user) {
firebase
.auth()
.createUser({
email: user.email,
password: user.password,
displayName: `${user.firstName} ${user.lastName}`
})
// After user is created make a email teamplate and send it
.then(function(userRecord) {
let resetLink = ''
// Welcome email template
const output = `
<p>You have access to the Church Mutual Assignment Tool.</p>
<p>Follow this link to create new password for your account ${userRecord.email}:</p>
<p>${this.resetLink}</p>
<p>Thanks,</p>
<p>Your Church Mutual Assignment Tool team</p>
`
let message = {
from: 'nyik6nntutmq3vz6#ethereal.email',
to: `${user.email}`,
subject: 'Welcome to the Church Mutual Assignment Tool',
text: 'Plaintext version of the message',
html: output
}
// Generate reset password and Send Email
//===== HERE IS PROBLEM THIS generatePasswordResetLink() "is not a fucntion"====== \\
admin.auth().generatePasswordResetLink(user.email, actionCodeSettings)
.then(link => {
// Send Email
transport.sendMail(message, (err, info) => {
if (err) throw new Error('Error with email', err)
})
return sendCustomPasswordResetEmail(user.email, user.displayName, link)
})
.catch(error => {
console.log('error', error)
})
})
}
You are most probably using a version of the Node.js Admin SDK that is < Version 6.2.0.
See the Firebase Admin Node.js SDK Release Notes here: https://firebase.google.com/support/release-notes/admin/node. The "email action link generation APIs for creating links for password reset, email verification and email link sign-in" were only added in November 2018, with Version 6.2.0.

Firebase Admin SDK - Create user with custom fields

I've been following the Firebase SDK Admin - Manager User docs and everything went find for me with it's system. Either way, i want to extend my users information with fields such as first name, last name, nacionality, etc etc.
Right now i'm using Vue.JS (fronted), Axios (Http client) and Express.js (server) to manage my project and this is the way i create my users:
Vue.JS createUser method:
createUser() {
axios.post('http://localhost:3000/users',
{
username: this.username,
email: this.email,
firstName: this.firstName,
lastName: this.lastName,
password: this.password,
}).then(r => {
console.log(r)
}).catch(e => {
console.log(e)
})
// createUser
}
Each field: username, email, firstName, etc... got its value form a common HTML Form and they work just fine.
This is my "user create" route on the server side:
router.post('/', function (req, res, next) {
firebase.auth().createUser({
email: req.body.email,
username: req.body.username,
firstName: req.body.firstName,
lastName: req.body.lastName,
emailVerified: false,
password: req.body.password,
disabled: false
}).then(function(userRecord) {
console.log("Successfully created new user:", userRecord.uid);
}).catch(function(error) {
console.log("Error creating new user:", error);
});
});
And this is how i retrieve the users information:
router.get('/', function(req, res, next) {
firebase.auth().listUsers()
.then(function(listUsersResult) {
res.send(listUsersResult.users);
}).catch(function(error) {
console.log("Error listing users:", error);
})
});
The problem is that i can't get the custom fields i added (or they simply does not exists). Here's is a pictures of the data once i get it with the next method:
getItems() {
axios.get('http://localhost:3000/users').then(r => {
this.users = r.data
}).catch(e => {
console.log(e)
})
},
Is there a way to set custom fields on my user creation or (if my process is right) a way to retrieve them?
Firebase users are not customizable, unfortunately you can not add custom fields to the user... check out these docs for the properties of this object. Also check out this question & answer where Frank explains that you need to store any extra info separately... this is typically done in a table (named something like /userDetails) in your database.
FEBRUARY 2022 EDIT:
Since writing this answer, custom user claims are now a thing. It's meant for authentication / rules purposes and not data-storage, so most things should still be kept in the database as originally stated. Note that you CAN access the custom fields client-side.
Keep in mind, this is adding additional data to the ID token that gets sent with EVERY server request, so you should try to limit usage of this to role/permission based things and not, say, image data for a 2nd profile avatar. Read the best practices for custom claims on the official docs.
You can set a user's profile, immediately after creating.
firebase.auth().createUserWithEmailAndPassword(
email,
password,
).then(credential => {
if (credential) {
credential.user.updateProfile({
displayName: username
})
}
}

Resources