I have a signup screen in my app which contains few things:
full name,email and password.
I want to add the users full name and in the future a phone number (for example) to the realtime database.
How can I do so?
I'm using onCreate from firebase cloud functions to add a photoUrl and email to the database, but couldn't find a way to add my own properties such phone number,city,full name etc.
In the end result, I want to have a registration form with all of the above properties.
How can I do so?
This is my onCreate method:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const ref = admin.database().ref()
exports.createUserAccount = functions.auth.user().onCreate(event=>{
const uid = event.data.uid
const email = event.data.email
const photoUrl = event.data.photoUrl || 'https://vignette1.wikia.nocookie.net/paulblartmallcop/images/9/9c/Person-placeholder-male.jpg/revision/latest?cb=20120708210100'
const newUserRef = ref.child(`/users/${uid}`)
return newUserRef.set({
photoUrl: photoUrl,
email: email,
})
});
How can I add more properties to the user?
If you are looking to store your user details in firebase, use firebase database instead. Try this.
{
"userList": {
"JRHTHaIsjNPLXOQivY": {
"fullName": "UmarZaii",
"phoneNumber": "0123456789"
},
"JRHTHaKuTFIhnj02kE": {
"fullName": "JohnDoe",
"phoneNumber": "0123456789"
}
}
}
You have to create a function that saves your data to the database after you successfully created the account.
Make sure that you save all the details inside userID.
For more information on how to save data to firebase database check Firebase Documentation.
Related
This question already has answers here:
Firebase kicks out current user
(19 answers)
Closed 1 year ago.
I want to make a system where the administrator can create user auth from an email. I have developed as the documentation says but the current session is closed. I only want to create the auth to get the uid and then create a user in the database with the data I want to store.
This is what I have:
var email = emailInput.value;
var password = "Abcd1234";
firebase.auth().createUserWithEmailAndPassword(email, password).then((userCredential) => {
var user = userCredential.user;
//user.uid contains the id I want to create the instance on ref usuarios
database.ref("usuarios/"+ user.uid).set({...});
});
Edit:
You cannot create new users using client SDK. By that I mean a user creating new users as required. You need to use Firebase Admin SDK (which must be in a secure server environment - like Firebase Cloud Functions).
You can write a cloud function like this:
exports.createNewUser = functions.https.onCall((data, context) => {
if (isAdmin(context.auth.uid)) {
return admin.auth().createUser({
email: data.email,
password: data.password,
displayName: data.name
}).then((userRecord) => {
// See the UserRecord reference doc for the contents of userRecord.
console.log('Successfully created new user:', userRecord.uid);
return { uid: userRecord.uid }
}).catch((error) => {
console.log('Error creating new user:', error);
return { error: "Something went wrong" }
});
}
return {error: "unauthorized" }
})
Now there are multiple ways you could verify that the user who is calling this function is an admin. First one would be using Firebase Custom Claims which are somewhat like roles you assign to users. Another option would be storing UID of using in database and checking the UID exists in admin node of db. Just make sure only you can edit that part of the database.
To call the function from client:
const createNewUser = firebase.functions().httpsCallable('createNewUser');
createNewUser({ name: "test", email: "test#test.test", password: "122345678" })
.then((result) => {
// Read result of the Cloud Function.
var response = result.data;
});
Problem
I'd like to add several user data to firestore Authenticateced user list AND to users collection which I created by myself at same time, but it does't go well. users collection are updated only its part of it.
Data
// javascript
users: [
{email: "n_0#example.com", username: "user0"},
{email: "n_1#example.com", username: "user1"},
{email: "n_2#example.com", username: "user2"},
{email: "n_3#example.com", username: "user3"},
{email: "n_4#example.com", username: "user4"}
]
Code
// javascript
import * as app from 'firebase/app'
import 'firebase/auth'
const config = JSON.parse(process.env.VUE_APP_FIREBASE_CONFIG)
app.initializeApp(config)
export const firebase = app
export const auth = app.auth()
function asyncCreateUser(user) {
return auth.createUserWithEmailAndPassword(
user.email,
'password'
).then(function (createdUser) {
console.log('---')
console.log('user.email', user.email)
console.log('createdUser', createdUser.user.email)
const ref = usersRef.doc(createdUser.user.uid)
return ref.set(user)
})
}
this.users.map(user => asyncCreateUser(user))
Result
Authenticated users are ok.
users collection has problem: it has only three users in the collection. The number of users added to user collection may differ in different execution.
Log
Debug.vue?2083:50 user.email n_3#example.com
Debug.vue?2083:51 createdUser n_2#example.com
Debug.vue?2083:49 ---
Debug.vue?2083:50 user.email n_2#example.com
Debug.vue?2083:51 createdUser n_1#example.com
Debug.vue?2083:49 ---
Debug.vue?2083:50 user.email n_1#example.com
Debug.vue?2083:51 createdUser n_1#example.com
Debug.vue?2083:49 ---
Debug.vue?2083:50 user.email n_0#example.com
Debug.vue?2083:51 createdUser n_0#example.com
Debug.vue?2083:49 ---
Debug.vue?2083:50 user.email n_4#example.com
Debug.vue?2083:51 createdUser n_4#example.com
It's strange that in some section, user.email and createdUser are diffrent.
Help wanted
I'd like to know how to fix it. If possible, I'd like to know the causes too. Thank you!
Just a guess - you are using the javascript SDK to create the user, not the admin SDK.
The Javascript SDK logs the user in after creating the account, so basically you rapidly logged a new account in and out 5 times in a row, hence the mix up with the user ids when creating the firestore documents - it can be that you were just logged out at that moment:
If the new account was created, the user is signed in automatically.
Have a look at the Next steps section below to get the signed in user
details.
Firebase docs
If you want to bulk-create user accounts you are better off using the admin SDK in a secure environment (e.g. cloud functions) and simply trigger the https function from your frontend. The way you are doing it now means that all the accounts will be created sequentially which can be quite time consuming when you create lots at once - if you are using a cloud function and the admin sdk you can kick off the creation of all accounts in parallel and return a promise once all are finished - something along the lines of:
return Promise.all(users.map(user => admin.auth().createUser(user)
.then(function(userRecord) {
return admin.firestore().collection('users').doc(userRecord.uid).set(...);
})
})
Firebase admin reference
I solved it by my self. It seems async call in map made something wrong.
self = this
for (let i = 0; i < 5; i++) {
const self = this
await auth.createUserWithEmailAndPassword(data[i].email, 'password')
.then(function (res) {
const ref = usersRef.doc(res.user.uid)
self.data[i]._id = res.user.uid
ref.set(self.data[i])
}
)
}
I promise i thoroughly checked through all the previous asked questions and there isn't anything similar to this. I have a firebase function that listens to onCreate on a firestore collection.
exports.sendEmail = functions.firestore.document('/Users/{documentId}')
.onCreate((snap, context) => {
const username = snap.data().username;
const email = snap.data().email;
console.log(username, email)
const mailRef = functions.firestore.document('/mail')
return mailRef.ref.set({
email: email,
subject: 'Welcome'
});
});
After a document is created in Users, i want to take the data in users and create a new document in a main collection called mail. Is this possible because i've read the docs like 10 times and there's nothing on this. Any help is highly appreciated.
To create a document in cloud functions, then you need to use the admin sdk, so first install the package:
npm install firebase-admin --save
initialize the admin sdk:
const admin = require('firebase-admin');
admin.initializeApp({
credential: admin.credential.applicationDefault()
});
const db = admin.firestore();
Then you can add:
const mailRef = db.collection('mail')
return mailRef.add({
email: email,
subject: 'Welcome'
});
https://googleapis.dev/nodejs/firestore/latest/CollectionReference.html#add
I know this is coming a bit late, just incase anyone found themselves with this same question.When you use set() to create a document, you must specify an ID for the document to create. so basically the above code just takes a little tweak as follows
exports.sendEmail = functions.firestore.document('/Users/{documentId}')
.onCreate((snap, context) => {
const username = snap.data().username;
const email = snap.data().email;
const uid = context.params.documentId //get the doc ID
const alternateUid = //you can generate a random ID here
console.log(username, email)
const mailRef = firestore.collection("mail").doc(uid)
return mailRef.set({
email: email,
subject: 'Welcome'
});
});
But sometimes there isn't a meaningful ID for the document or you don't want to use any of the above. Then it's more convenient to let Cloud Firestore auto-generate an ID for you. You can do this by calling add(), as such
const mailRef = firestore.collection("mail")
return mailRef.add({
email: email,
subject: 'Welcome'
})
I have stored some data in firestore. There is collection(books) which link to document(book id)and book id has field like name, image,location,title.
I have another collection(Users) which has document(user id)user id has field as token id .Whenever there will be any write operation in book collection then I have to send notification to all the user using token id .
I am able to send notification to all user if I have hard-coded token id in my index.js file of firestore.
But I have to send notification dynamically. I am not able to read user id from collection users.
'use-strict'
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.firestore.document("Books/{book_id}").onWrite((change, context) => {
const book_id = context.params.book_id;
console.log("Book ID: " + book_id);
return admin.firestore().collection("Users").doc(user_id).collection("Notifications").doc(notification_id).get().then(queryResult => {
const tokenid= queryResult.data();
const token_id='fOGd94em4ik:APA91bHyZBGBYvO_ZFlLO1lWL1LU-r-1JkuF3fuKieWvV4HuPDKAiG5hdn-BQrMPFeICBdKZ3UR2nkM2PMxClEzVI3V2C38OxoP-1w71Dz-GbO0sbDlg-nswCMZ';
const payload = {
notification : {
title : 'Hi',
body : 'New Books list is available in the database! Please check the book store',
icon : "default"
}
};
return admin.messaging().sendToDevice(token_id, payload).then(result => {
//console.log("Notification sent");
return 0;
});
});
});
In above code I want to read user_id from collection users. How can I read it since it is not linked with collection books ,I am not able to read.
If I understand well and if token_id is a key in users record, you may try something like this:
admin.firestore().collection('Users')
.where('token_id', '==', 'YOUR_TOKEN').get()
.then(snap => snap.docs.map(user => {
// iterate on your notification process
})
I am wondering how to make a document for each user as they create their account (with Firebase Web). I have Firebase Authentication enabled and working, and I'd like each user then to have a document in Cloud Firestore in a collection named users. How would I get the UID and then automatically create a document for each user? (I am doing this so that calendar events can be saved into an array field in the document, but I need a document for the user to start with). I am aware and know how to make security rules for access, I just don't know how to make the document in the first place.
Thanks!
While it is definitely possible to create a user profile document through Cloud Functions, as Renaud and guillefd suggest, also consider creating the document directly from your application code. The approach is fairly similar, e.g. if you're using email+password sign-in:
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(function(user) {
// get user data from the auth trigger
const userUid = user.uid; // The UID of the user.
const email = user.email; // The email of the user.
const displayName = user.displayName; // The display name of the user.
// set account doc
const account = {
useruid: userUid,
calendarEvents: []
}
firebase.firestore().collection('accounts').doc(userUid).set(account);
})
.catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
Aside from running directly from the web app, this code also creates the document with the user's UID as the key, which makes subsequent lookups a bit simpler.
You´ll have to set a firebase function triggered by the onCreate() Auth trigger.
1. create the function trigger
2. get the user created data
3. set the account data.
4. add the account data to the collection.
functions/index.js
// Firebase function
exports.createAccountDocument = functions.auth.user().onCreate((user) => {
// get user data from the auth trigger
const userUid = user.uid; // The UID of the user.
//const email = user.email; // The email of the user.
//const displayName = user.displayName; // The display name of the user.
// set account doc
const account = {
useruid: userUid,
calendarEvents: []
}
// write new doc to collection
return admin.firestore().collection('accounts').add(account);
});
If you are using Firebase UI to simplify your life a lil, you can add a User document to a "/users" collection in Firestore only when that user first signs up by using authResult.additionalUserInfo.isNewUser from the signInSuccessWithAuthResult in your UI config.
I'm doing something like this in my project:
let uiConfig = {
...
callbacks: {
signInSuccessWithAuthResult: (authResult) => {
// this is a new user, add them to the firestore users collection!
if (authResult.additionalUserInfo.isNewUser) {
db.collection("users")
.doc(authResult.user.uid)
.set({
displayName: authResult.user.displayName,
photoURL: authResult.user.photoURL,
createdAt: firebase.firestore.FieldValue.serverTimestamp(),
})
.then(() => {
console.log("User document successfully written!");
})
.catch((error) => {
console.error("Error writing user document: ", error);
});
}
return false;
},
},
...
}
...
ui.start("#firebaseui-auth-container", uiConfig);
The signInSuccessWithAuthResult gives you an authResult and a redirectUrl.
from the Firebase UI Web Github README:
// ...
signInSuccessWithAuthResult: function(authResult, redirectUrl) {
// If a user signed in with email link, ?showPromo=1234 can be obtained from
// window.location.href.
// ...
return false;
}