I am updating a single field name, which is "name", I am successful on editing it, but it creates another node. like this
This is my Code:
const user = firebase.auth().currentUser;
let uid;
if (user != null) {
uid = user.uid;
const db = firebase.firestore();
const docRef = db.collection('users').doc(uid);
docRef.update({
name,
timestamp: firebase.firestore.FieldValue.serverTimestamp()
}).then(() => {
console.log('Profile Successfully Edited!');
}).catch((error) => {
console.log('Error updating the document:', error);
})
}
I already found the solution,
if (user != null) {
uid = user.uid;
const db = firebase.firestore();
db.collection('users').doc(uid).update({
name })....
I just directly put the .update unto the db reference.
Try
docRef.update({
name:"Christian",
timestamp: firebase.firestore.FieldValue.serverTimestamp()
})
You can pass a string var after name:
Related
Hey for my current project I have a component that is able to create a user and add it into the database with
createUserWithEmailAndPassword(auth, email, password).
I am trying to create another component that will be able to edit the current user that is logged in. I am getting this error whenever I run the function below in my button
Uncaught (in promise) FirebaseError:
No document to update: projects/teamh-test-tien/databases/(default)/documents/users/6BKmEeZeoXNYpgfM6ms6WbgH5as1.
The function only works when I hard code the document id and replace it with the user.uid for ex.
const profileRef = doc(db, "users", '6BKmEeZeoXNYpgfM6ms6WbgH5as1');
How would I be able to grab the document id then? I assumed the user.uid specified which document has that user id.
const handleUpdate = async (e) => {
e.preventDefault();
const profileRef = doc(db, "users", user.uid);
// console.log('event--->', e);
console.log('user id --->', user.uid);
console.log('profileRef--->', profileRef);
const profileDoc = await getDoc(profileRef).catch((error) =>
console.error(error)
);
if (!profileDoc) {
console.error('No document found for this user ID');
return;
}
console.log('profileDoc--->', profileDoc);
// const profile = await getDoc(profileRef);
// console.log('profile--->', profile.data());
await updateDoc(profileRef, {
name,
// name: name,
}).then(() => console.log('updated!', auth.currentUser.displayName));
};
This is my db structure:(https://i.stack.imgur.com/r2EsB.png)
This is how I create users and add it into the db:
const registerWithEmailAndPassword = async (name, email, password) => {
try {
const auth = getAuth();
const res = await createUserWithEmailAndPassword(auth, email, password);
const user = res.user;
// console.log('user created', user)
await addDoc(collection(db, "users"), {
uid: user.uid,
name,
authProvider: "local",
email,
});
console.log('user auth', auth.currentUser)
await updateProfile(user,{
displayName: name,
})
await user.reload()
console.log('user updated', user)
} catch (err) {
console.error(err);
alert(err.message);
}
};
I've tried this which creates a new doc that would be the specific user.uid that was created when you
createUserWithEmailAndPassword(auth, email, password).
// const handleUpdates = async (e) => {
// e.preventDefault()
// const profileRef = doc(db, "users", user.uid);
// await setDoc(profileRef, {
// name,
// }, { merge: true }).then(() => console.log('updated!', auth.currentUser.displayName))
// };
This is how the handleUpdates function work
If you want to set a document's ID when adding it, use the setDoc() method instead...
await setDoc(doc(db, "users", user.uid), {
name,
authProvider: "local",
email,
});
This will allow you to retrieve documents by the auth user uid.
For more information, see Add a document
When you use set() to create a document, you must specify an ID for the document to create
Using addDoc() auto-generates an ID which won't match your user uid properties.
I have below is a method that signs a user up with their email and password and create a document in Firebase when the user enters their info into a form and clicks submit:
const onSubmitHandler = async (e) => {
e.preventDefault();
try {
const { user } = await createAuthUserWithEmailAndPassword(email, password);
console.log(user, 'user')
await createUserDocumentFromAuth(user, { displayName })
}catch(err) {
if(err === 'auth/email-already-in-use') {
alert('Account with this email already exists');
return;
}else {
console.log(err)
}
}
}
For this function call:
await createUserDocumentFromAuth(user, { displayName })
where displayName can be a string, such as ElonMusk.
In the actual createUserDocumentFromAuth, I am calling the setDoc method, which is one from Firebase to set a user document:
export const createUserDocumentFromAuth = async ( userAuth, additionalInfo = {} ) => {
if(!userAuth) return;
console.log(additionalInfo, 'additionalInfo')
const userDocRef = doc(db, 'users', userAuth.uid);
const userSnapshot = await getDoc(userDocRef);
if(!userSnapshot.exists()) {
const { displayName, email } = userAuth;
const createdAt = new Date();
try {
// set the doc here
await setDoc(userDocRef, {
displayName,
email,
createdAt,
...additionalInfo
});
} catch(err) {
console.log('err creating the user', err)
}
};
return userDocRef;
}
The reason I passed { displayName } in manually is because there is a case where the server's response to createAuthUserWithEmailAndPassword(email, password) has displayName to be null, but we want the user to have a displayName registered in the database.
My question is:
Why does displayName only work when it is passed in as an object and not just in its normal form? For example:
await createUserDocumentFromAuth(user, { displayName })
will replace the displayName: null
But not when I pass in:
await createUserDocumentFromAuth(user, displayName)
What is this technique called in JavaScript?
If you look into createUserDocumentFromAuth, you'll see that it's expects two arguments userAuth and additionalInfo, both arguments are expected to be objects.
It later uses data from additionalInfo to add/overwrite anything in userAuth when calling setDoc() method.
So, I'd recommend add
console.log(userDocRef, {
displayName,
email,
createdAt,
...additionalInfo
});
to see what what data is being sent to setDoc()
I want to get only the document specified by where.
Store the email address registered in the uid property as a value in the Firestore at the time of new registration.
async signUp() {
const db = firebase.firestore();
await this.$store.dispatch('signUp', { username:this.username, email:this.email, password:this.password });
await db.collection('myData').doc(this.username).set({
uid: this.email,
email: this.email,
myWallet: 1000
});
this.$router.push('/home');
}
async signUp({ commit }, userInfomation) {
try {
await firebase
.auth()
.createUserWithEmailAndPassword(
userInfomation.email,
userInfomation.password
);
const user = firebase.auth().currentUser;
await user.updateProfile({
displayName: userInfomation.username,
});
commit('setUserName', user);
} catch (e) {
alert(e.message);
}
},
mutations: {
setUserName(state, user) {
state.userName = user.displayName;
},
actions: {
async getMyWallet({ commit, state }) {
const uid = state.updateUserName.email; //Information on the logged-in user is stored in updateUserName.
const db = firebase.firestore();
const doc = await db
.collection('myData')
.where('uid', '==', uid)
.get();
commit('getMyWallet', doc);
}
}
When I ran it, I got the error written in the title.
Is it written incorrectly?
Is there any other good way?
async getMyWallet({ commit }) {
firebase.auth().onAuthStateChanged(user => {
const uid = user.email;
const db = firebase.firestore();
const doc = db
.collection('myData')
.where('uid', '==', uid)
.get();
commit('getMyWallet', doc);
});
},
When I rewrote the getMyWallet part, I got a new error.
Error details: doc.data is not a function
I build a react native signUp form with this fields (email, password, name, and phone) and I need to add it to the firebase database when user create his account.
I create the signUp function like this:
onSignUpPress() {
const navigation = this.props.navigation;
this.setState({ error: '', loading: true });
const { email, password } = this.state;
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(() => {
this.setState({ error: '', loading: false });
navigation.navigate("Profile");
})
.catch(() => {
this.setState({ error: 'Authentication failed.', loading: false });
console.log("Error creating user:");
});
}
and it's work
I need to know how can I add the field to a database
I try this :
writeUserData(uid, name, email, phone) {
let userId = firebaseApp.auth().currentUser.uid;
var newUser = {
name: name,
email: email,
phone: phone
}
var newUserKey = firebase.database().ref().child('users').push().key;
var updates = {};
updates['/users/' + newUserKey] = newUser;
updates['/user-users/' + uid + '/' + newPostKey] = postData;
return firebase.database().ref().update(updates);
}
onSignUpPress() {
....
....
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(() => {
....
this.writeUserData(uid, name, email, phone);
navigation.navigate("Profile");
})
....
.....
}
but it's not working correctly any help, please?
Firebase has many functionalities. Out of them two are authentication and real time database.
When you call createUserWithEmailPassword successfully, it automatically creates a UID of the user and stores the meta in Firebase Authentication.
You can now at point of time get this UID of this user when he is authenticated using firebase.auth(). currentUser.uid and then create a firebase reference where you want to save data database.ref().child(path)
Use the .set(object) or .push(object) to save data.
Tip : Create your database architecture properly (see documentation) to be able to fetch the saved data properly.
try this,
writeUserData(uid, name, email, phone) {
const userId = firebase.auth().currentUser.uid;
//You don't have to create key because userId is uniq value.
return firebase.database().ref(`users/${userId}`).update({name, email, phone});
}
onSignUpPress() {
....
....
// createUserWithEmailAndPassword promise resolve return userData!
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(userData => {
....
this.writeUserData(userData.uid, name, email, phone);
navigation.navigate("Profile");
})
....
.....
}
and I don't get it why you try to update,
updates['/user-users/' + uid + '/' + newPostKey] = postData;
even if you don't have postData at this moment!
You just set when user create post data like this
writePostData(uid, postData) {
const postRef = firebase.database().ref(`user-users/${uid}`);
//this way is useful when key handling before push
var push = postRef.push();
var key = push.key;
return postRef.child(key).set(postData);
//or just push
return postRef.push(postData);
}
I want to create users with the function createUserWithEmailAndPassword and then put the data of that user into my database but it doesn't work.. the user is added to my authentication tab in firebase but not in my database. I also don't get an error.
registerUser.addEventListener('click', function (user) {
event.preventDefault();
closeRegisterForm();
email = registerEmail.value;
password = registerPassword.value;
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(function (event) {
var ref = firebase.database().ref("users").child(user.uid).set({
email: user.email,
uid: user.uid
});
})
.catch(function (error) {
var errorCode = error.code;
var errorMessage = error.message;
});
});
Hi I was having the exact same problem. But i used a local function to solve it. Something like this:
createNewUser(form) {
//create new user with provided data of the form
this.afAuth.auth.createUserWithEmailAndPassword(form.email, form.password)
.then(function(firebaseUser) {
console.log("User " + firebaseUser.uid + " created successfully!");
updateFirestore(form, firebaseUser.uid);
return firebaseUser;
}).catch(function(error) {
alert(error)
});
function updateFirestore(form, uidNewUser) {
//push data into firestore using the uid provided
let data = {};
data['mail'] = form.email;
data['name'] = form.name;
//se empuja el arreglo data en el documento del usuario
this.afs.collection('users').doc(uidNewUser).set(data);
console.log(data, uidNewUser);
}
}
You refer to user.uid and user.email but never define user. The return type of sign in method createUserWithEmailAndPassword is a user but you define it as event. Also make sure you wait for the db write promise to resolve and catch any errors there as Frank advised.
Working for me:
const val = this.signupForm.value;
this.authService.doRegister(val)
.then(res => {
this.msg = 'You have registered successfully!';
this.msgType = 'success';
this.authService.updateUser(val.name, null)
.then(suc => {
const created = firebase.firestore.FieldValue.serverTimestamp();
const user = {
first_name: val.name,
last_name: '',
email_personal: val.email,
created: created,
updated: created
};
this.userCollection = this.afs.collection<User>('users');
this.userCollection.doc(suc).set(user);
}, err => {
// console.log(err);
});
this.router.navigate(['/']);
}, err => {
this.msg = err.message;
})
const [phone, setPhone] = useState()
const [email, setEmail] = useState()
const [password, setPassword] = useState()
const handleSignUp = async () => {
if (!email == ' ' && !password == ' ') {
try {
const result = await auth().createUserWithEmailAndPassword(email, password)
firestore()
.collection('Users')
.doc(result?.user?.uid)
.set({
email: result?.user?.email,
phoneNumber: phone,
uid: result?.user?.uid,
displayName: result?.user?.email.split('#')[0],
})
.then(() => {
alert('User added!');
});
} catch (error) {
if (error.code === 'auth/email-already-in-use') {
Alert.alert('That email address is already in use!');
}
else if (error.code === 'auth/invalid-email') {
Alert.alert('That email address is invalid!');
}
else {
Alert.alert(error)
}
}
} else {
Alert.alert("Please Enter Your All Field");
}
}