How do you make a relationship in firebase and use the fields? I'm picking up here. I'm working with firestore here and I made relationships like this:
Where I have the collection of answers and it has serviceId collaboratorId and tokenId each of these there is a foreign key of the other collections that you can see in the image. I don't know if this is right, but assuming it's right anyway, how do you use this in React? When it was all string I could add it, now that it's changed to a reference it doesn't work anymore :(
To add I was doing this:
async function handleSubmitResult(e) {
e.preventDefault();
await createFormSchema
.validate({
name,
service,
collaborator,
})
.then(() => {
addDoc(answersCollectionRef, {
name,
service,
collaborator,
answer1,
answer2,
answer3,
answer4,
comment,
createdAt: new Date().toString(),
});
console.log("SALVO NO FIREBASE! 🔥");
// A temporary fix to clear fields of the form
document.getElementById("form-rating").reset();
setName("");
setService("");
setCollaborator("");
setAnswer1(0);
setAnswer2(0);
setAnswer3(0);
setAnswer4(0);
setComment("");
navigate("/thanks");
})
.catch((error) => {
toast.error(error.message, {
theme: "colored",
});
});
}
This works perfectly when it was a string, but now that the fields have changed to the references of the collections I mentioned, I can no longer save it the way I want it in the firestore.
---- After edit my question ------
And when I edit my save method to:
async function handleSubmitResult(e) {
e.preventDefault();
await createFormSchema
.validate({
name,
service,
collaborator,
})
.then(() => {
addDoc(answersCollectionRef, {
name,
serviceId: service,
collaboratorId: collaborator,
answer1,
answer2,
answer3,
answer4,
comment,
createdAt: new Date().toString(),
tokenId: token,
});
console.log("SALVO NO FIREBASE! 🔥");
// A temporary fix to clear fields of the form
document.getElementById("form-rating").reset();
setName("");
setService("");
setCollaborator("");
setAnswer1(0);
setAnswer2(0);
setAnswer3(0);
setAnswer4(0);
setComment("");
navigate("/thanks");
})
.catch((error) => {
toast.error(error.message, {
theme: "colored",
});
});
}
It doesn't show any errors, it now is saving, but it saves as a string. Wouldn't it be correct to save the ID, given that I'm doing a one-to-many relationship? That's what I can't understand...
My firebase looks like this after saving:
------ Add ID of the document Service
Here is my Service, how get id document?
If you want to store a reference to another document in the database, make sure that the value you pass in your code is a DocumentReference object to that document.
E.g. say that you want the name field to be a DocumentReference to the Users collection, that'd be something like:
addDoc(answersCollectionRef, {
name: new DocumentReference(db, "Users", "idOfUserDocument"),
...
});
Related
i am developing a todolist application so that for each user i store the activities of a user in an array. schema of user look like this.
const activitySchema=new mongoose.Schema({
activity:String
})
const Activity=new mongoose.model("activity",activitySchema)
const userSchema=new mongoose.Schema({
username:String,
password:String,
activities:[],
});
i used pull command to delete a specific activity from user actvities list
app.post("/delete",(req,res)=>{
User.updateOne( {username: req.user.username}, { $pull: { activities: { _id: req.body.activity} }
}, function(err, model){
if(err)
console.log(err);
else {
console.log(model)
res.redirect("/")
}
})
})
this code is working after user clicks for 5-10 times on delete button but not immediately. the log output showing matched document:1 and modified document:0. kindly assist
For Modifying the document you need to save the model after making every change to the model.
activity.save().then(()=>{ console.log("Document Saved"))
Similar is the for the other document where you are making a change, You can read more about it if you want Mongoose
I want to do something like this in the firestore
const sendwant = (f) => {
fire
.firestore()
.collection("Rooms")
.doc(f.roomname)
.collection("wants")
.doc()
.where("user","!=",f.displayName)
.set({
user: user.displayName,
status: false,
roomname: f.roomname,
created: f.user,
date: firebase.firestore.FieldValue.serverTimestamp(),
})
.then(() => {
alert("You sent a request to join this room wait for an answer");
});
};
Since I don't want multiple same users in the collection, I want this operation to run when the user value is not equal to the displayName value. If you know another way please help me
This never will give any results:
.collection("wants")
.doc()
.where("user","!=",f.displayName)
The doc() call in here creates a reference to a new, non-existing, unique document. And you when filter that for only documents with a specific condition.
If you want all documents from wants with a different display name, that'd be:
.collection("wants")
.where("user","!=",f.displayName)
Mongoose/MongoDB Question
I have an Owners model containing basic profile data.
I have a secondary model: OwnersImages
e.g
{
owner: {
type: Schema.Types.ObjectId,
ref: 'Owners'
},
name: String,
imageUrl: String,
},
);
From the client I want to post the imageUrl and the name to the OwnersImages table.
e.g
let values = {
owner: this.state.user._id,
name: this.state.field,
imageUrl: this.state.url
}
axios.post(`${serverPath}/api/addFieldImage`, values)
However Im unsure how best to go about this, link it etc.
I can do a GET request on the Owners table to get the Owner data, but then posting this as part of the values to OwnerImages doesn't successfully link the two tables.
Do i need to just store a string reference to the Owner id in OwnerImages or is there a smarter way of doing this?
Or should I just post the string of the user Id to mongoose and then do a map to the Owner table from within there?
Tried to explain this best way I could but the eyes are tired so please ask if any confusion!
Many thanks
Without seeing your exact setup, I think you could modify this to fit your needs:
// In the Schema/Model files
const ownersSchema = Schema({
// other fields above...
images: [{ type: Schema.Types.ObjectId, ref: 'OwnersImages' }]
});
const ownersImagesSchema = Schema({
// other fields above...
owner: { type: Schema.Types.ObjectId, ref: 'Owners' },
});
// in the route-handler
Owners.findById(req.body.owner, async (err, owner) => {
const ownersImage = new OwnersImages(req.body);
owner.images.push(ownersImage._id);
await ownersImage.save();
await owner.save();
});
As a side-note, I think the Models generally have singular names, so Owner and OwnerImage. The collection will then automatically take on the plural form. Just food for thought.
When you want to load these, you can link them with populate(). Consider loading all of the OwnersImages associated with an Owners in some route-handler where the /:id param is the Owners id:
Owners
.findOne({ _id: req.params.id })
.populate('images')
.exec(function (err, images) {
if (err) return handleError(err);
// do something with the images...
});
EDIT: Since I wasn't able to find a correct solution, I changed the
application's structure a bit and posted another question:
Mongoose - find documents not in a list
I have a MEAN app with three models: User, Task, and for keeping track of which task is assigned to which user I have UserTask, which looks like this:
const mongoose = require("mongoose");
const autopopulate = require("mongoose-autopopulate");
const UserTaskSchema = mongoose.Schema({
completed: { type: Boolean, default: false },
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
autopopulate: true
},
taskId: {
type: mongoose.Schema.Types.ObjectId,
ref: "Task",
autopopulate: true
}
});
UserTaskSchema.plugin(autopopulate);
module.exports = mongoose.model("UserTask", UserTaskSchema);
In my frontend app I have AngularJS services and I already have functions for getting all users, all tasks, and tasks which are assigned to a particular user (by getting all UserTasks with given userId. For example:
// user-task.service.js
function getAllUserTasksForUser(userId) {
return $http
.get("http://localhost:3333/userTasks/byUserId/" + userId)
.then(function(response) {
return response.data;
});
}
// task-service.js
function getAllTasks() {
return $http.get("http://localhost:3333/tasks").then(function(response) {
return response.data;
});
}
Then I'm using this data in my controllers like this:
userTaskService
.getAllUserTasksForUser($routeParams.id)
.then(data => (vm.userTasks = data));
...and because of autopopulate plugin I have complete User and Task objects inside the UserTasks that I get. So far, so good.
Now I need to get all Tasks which are not assigned to a particular User. I guess I should first get all Tasks, then all UserTasks for a given userId, and then make some kind of difference, with some "where-not-in" kind of filter.
I'm still a newbie for all the MEAN components, I'm not familiar with all those then()s and promises and stuff... and I'm really not sure how to do this. I tried using multiple then()s but with no success. Can anyone give me a hint?
You can do at server/API side that will more efficient.
In client side, if you want to do then try below
var userid = $routeParams.id;
userTaskService
.getAllTasks()
.then((data) => {
vm.userTasks = data.filter(task => task.userId !== userid)
});
I'm working through a mongoDB tutorial, and the instructor suggests I use the following code to validate the entry of a user into my database. I have already defined a User model, which just accepts a name, and looks like this:
it("Can create a subdocument", (done) => {
const joe = new User({
name: "joe",
});
joe.save()
.then(() => User.findOne({ name: "joe"}))
.then((user) => {
assert(user.name === "joe")
done();
});
}
However, I don't understand why using the User.findOne function is necessary here. Why can't we just use:
joe.save().then((user) => {
assert(user.name === "joe")
done();
});
Thanks for your help!
If you want to validate the entry, means you need to make sure that the data is really inserted correctly on the db. How to do this is, after saving, you need to find the data directly to the db using findOne, then you validate that data you are getting, is that match with the one you intended to insert