Getting some problems in database saving - database

I'm getting problem in my database, I'm using mongoDB with mongoose npm package.
if (!authData) return res.redirect("/login")
const user = await process.oauth.getUser(authData.access_token);
// console.log(user)
let data = await Schema.findOne({
userID: user.id
})
if (!data) {
let e = await Schema.create({
userID: user.id,
})
await e.save()
let dataID = e._id.toString();
e.access_token = authData.access_token;
e.refresh_token = authData.refresh_token;
e.expires_in = authData.expires_in;
let secretAccessKeyy = jwt.sign({
userID: user.id,
uuid: dataID
}, jwtSecret)
/*
e.secretAccessKey = secretAccessKeyy
console.log(secretAccessKeyy)
*/
e.user = {
id: user.id,
username: user.username,
discriminator: user.discriminator,
avatar: user.avatar
};
await e.save()
await Schema.findOneAndUpdate({
userID: user.id
}, {
secretAccessKey: secretAccessKeyy
})
} else {
const id = data._id.toString();
data.access_token = authData.access_token;
data.refresh_token = authData.refresh_token;
data.expires_in = authData.expires_in;
let secretAccessKey = jwt.sign({
userID: user.id,
uuid: id
}, jwtSecret)
data.secretAccessKey = secretAccessKey
console.log(secretAccessKey)
data.user = {
id: user.id,
username: user.username,
discriminator: user.discriminator,
avatar: user.avatar
};
await data.save()
}
I have this code (its only data part not full code), it should check If there is data then overwrite data with new values other wise create a document, save It then again overwrite that document with new Objects then save.
Problems I'm Getting:
When I'm logging data its returning null but the data actually exists in database
the secretAccessKey is not saving in database
Would appreciate some help.
Thanks!

Related

How do I fetch a specific result from mongodb

I'm still new to reactjs and mongodb.I am trying to fetch a single record of user and display it on the page. But so far I got no output. I want the page to immediately display the result on load
This is my profile.js:
componentDidMount() {
const user = localStorage.getItem('user')
const userObject = {
username: localStorage.getItem('user'),
};
axios.post('http://localhost:4000/users/getUser', userObject)
.then((res) => {
console.log("hi"+res.data)
const userinfo = res.data
this.setState({
name: userinfo.name,
username: res.username,
email: res.email,
password: res.password,
company: res.company,
position: res.position
})
})
.catch(function (error) {
console.log(error);
})
}
and this is my backend(user.js):
let mongoose = require('mongoose'),
express = require('express'),
router = express.Router(),
user = require('../models/user-schema');
router.post('/getUser', async (req, res) => {
console.log(req.body.username)
const User = await user.find({ name: req.body.username })
if (!User) {
return { status: 'error', error: 'Invalid Login' }
}else {
return res.json({
status: 'ok',
name: User.name,
username: User.username,
email: User.email,
company:User.company,
position: User.position,
level: User.userLevel
})
}
})
user.find({ name: req.body.username }) is going to return an array. So in the code below, all those fields such User.name , User.username, User.email etc are going to be undefined since User = [{name:xxx,username:xxx }]
res.json({
status: 'ok',
name: User.name, // undefined
username: User.username, // undefined
email: User.email, // undefined
company:User.company, // undefined
position: User.position,// undefined
level: User.userLevel // undefined
})
You should use user.findOne({ name: req.body.username }) which will return a single object and then you can access the properties.
Additionally (Personal preference) , one might have multiple users with the same username. To make sure you're retrieving the correct docuemnt, rather use findById().
Instead of this find({}) you can use findOne({}) cause find({}) going to return an array but your are expecting an object that the the problem
Use findOne() instead of find() method, find() method returns an array of objects and findOne() method return a single particular object.
const User = await user.findOne({ name: req.body.username })
and you can pass specific filed which you want to get like
let User = await user.findOne({ name: req.body.username },{username:1, email:1, company:1, position:1, level:1});
if(!User){
return res.status(404).json({ status: 'error', error: 'Invalid Login' });
} else {
return res.status(404).json({status:"ok", ...User});
}

adding users to firestore with the same uid that it was created with

I am trying to add new users to firestore with the same uid, when they are creatd with createUserWithEmailAndPassword. however I can add users to my user collection, but the id its given is not the same id as the uid. this is how I do it:
const auth = getAuth(db);
const app = getFirestore();
const handleSubmit = useCallback(
async (event) => {
event.preventDefault();
const { email, password, fname, lname } = event.target.elements;
// console.log("clicked", email.value, password.value);
const auth = getAuth(db);
const app = getFirestore();
createUserWithEmailAndPassword(auth, email.value, password.value)
.then(async (userCredential) => {
// Signed in
const user = userCredential.user;
try {
const docRef = await addDoc(collection(app, "users"), {
firstName: fname.value,
lastName: lname.value,
email: email.value,
age: 0,
bday: "",
});
console.log("Document written with ID: ", docRef.id);
} catch (e) {
console.error("Error adding document: ", e);
}
//=================
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
// ..
});
},
[history]
);
the ref id it a different id than my uid.
what do I have to do to make it save the user with the same id.
also I have tried this
app.collection("users")
doc(user.uid)
.set({...})
but this generates an error!
If you check the Web version 9 (modular) code sample in the documentation on setting a document, you'll see that setting the document goes like this:
import { doc, setDoc } from "firebase/firestore";
// Add a new document in collection "cities"
await setDoc(doc(db, "cities", "LA"), {
name: "Los Angeles",
state: "CA",
country: "USA"
});
So in your scenario, that'd be:
const docRef = doc(app, "users", user.uid)
await setDoc(docRef, {
firstName: fname.value,
lastName: lname.value,
email: email.value,
age: 0,
bday: "",
});

How to add async functionality to a Firebase 'put' and 'set' query operation

I have been using the following function to store a file in Firebase Storage, return the URL, which I then store along with some other fields, in Firestore.
Where do I add an 'await' or how do I add a promise so that the 'history.push("/") is not called until all operations have completed? At the moment I think it's pushing me on to the next page before it's finished.
async function handleSubmit(e) {
e.preventDefault()
const collectionRef = useFireStore.collection('users').doc(`${currentUser.uid}`);
const storageRef = useStorage.ref("avatars")
const fileRef = storageRef.child(`${uuidv4()}`)
fileRef.put(file).then(() => {
fileRef.getDownloadURL().then(function (url) {
collectionRef.set({
createdAt: timestamp(),
email: currentUser.email,
userid: currentUser.uid,
username: username,
firstname: firstname,
lastname: lastname,
avatar: url
})
});
})
history.push("/")
}
What would be some best-practices here, please?
Kind regards, Matt
You can do something like this,
async function handleSubmit(e) {
e.preventDefault()
const collectionRef = useFireStore.collection('users').doc(`${currentUser.uid}`);
const storageRef = useStorage.ref("avatars")
const fileRef = storageRef.child(`${uuidv4()}`)
await fileRef.put(file);
const url = await fileRef.getDownloadURL();
await collectionRef.set({
createdAt: timestamp(),
email: currentUser.email,
userid: currentUser.uid,
username: username,
firstname: firstname,
lastname: lastname,
avatar: url
});
history.push("/")
}
Refer: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

Cant pass uid from created user firebase

I cant pass the uid from the newly created user that is created from a firebase cloud function. The user is created successfully but the document in collection of the firestore is not. When i remove the argument from .doc() like this the user is created but with the random generated uid not the one created from the create user ofc. What i would like is to pass the uid from the created user to as the doc name. The uid is available from the response of the createUsr function.
I think i'm not doing something right with the way i'm using the async function.
const handleSubmit = async (values) => {
const createUsr = functions.httpsCallable('createUsr')
try {
await createUsr({ email: values.email }).then((data) => {
const id = data.uid
const newDocRef = db.collection('students').doc(id)
newDocRef.set({
userID: id,
firstName: values.firstName,
lastName: values.lastName,
access_type: "student"
})
})
success()
} catch {
error()
}
}
Data response from the console
Object
data:
disabled: false
displayName: null
email: "test#gmail.com"
emailVerified: false
metadata: {creationTime: "Tue, 06 Apr 2021 19:06:19 GMT", lastSignInTime: null, lastRefreshTime: null}
passwordHash: null
passwordSalt: null
phoneNumber: null
photoURL: null
providerData: []
tenantId: null
tokensValidAfterTime: "Tue, 06 Apr 2021 19:06:19 GMT"
uid: "GHpc2ykVj3RPnMqPDDiDiViVvmc2"
__proto__: Object
__proto__: Object
Try with this:
const handleSubmit = async (values) => {
const createUsr = functions.httpsCallable('createUsr')
try {
createUsr({ email: values.email }).then(({ data }) => {
const { uid } = data;
const newDocRef = db.collection('students').doc(uid);
await newDocRef.set({
userID: uid,
access_type: "student",
...values
});
});
success();
} catch {
error()
}
}

Save user info into database just after registration in Firebase

I am trying to save a newly created user's info into Firestore using the uid as the document id. The problem I encounter comes after the creation of the user, in order to save his information into the Firestore collection after creation.
Here is what I have already tried:
const usersRef = firebase.firestore().collection('Users');
firebase.auth().createUserWithEmailAndPassword(values.email, values.password).then(function(user){
usersRef.doc(`${user.uid}`).set({
firstName: values.firstName,
lastName: values.lastName,
username: values.username,
uid: user.uid
})
}).catch(function(error){
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// [START_EXCLUDE]
if (errorCode == 'auth/weak-password') {
alert('The password is too weak.');
} else {
alert(errorMessage);
}
console.log(error);
// [END_EXCLUDE]
});
The code is expected to save the user's info after creation, but it causes the following error :
The collection document ID cannot be undefined or so
The method you're using using returns Promise<UserCredential>. Your code should be:
const usersRef = firebase
.firestore()
.collection('Users');
firebase
.auth()
.createUserWithEmailAndPassword(values.email, values.password)
.then(function(userCredential) {
usersRef
.doc(`${userCredential.user.uid}`)
.set({
firstName: values.firstName,
lastName: values.lastName,
username: values.username,
uid: userCredential.user.uid
})
...

Resources