Choosing the correct Data Structure in Firebase Firestore for my Flutter Todo App - firebase

I am currently developing a ToDo app with Flutter and Firebase. The initial situation is as follows:
1. the user has to log in when he wants to create ToDos, i.e. the ToDos would have to be saved best under the UID, right?
2. a user can create multiple lists/categories, for this I also thought about the structure and came up with 2 ideas.
First idea:
I have 2 collections, one with the UserID and all todos and one with the UserID and all categories.
todo ->
title,
createdAt,
done,
category, (link to the second collection with the categories)
...
category ->
name,
icon,
...
Second idea:
I create a single collection per user, the first field is then an array with the name of the category, and in this array are all ToDos.
Unfortunately, I am a complete beginner in Firestore and therefore I am not sure if any of my suggestions would make sense. I hope that the initial situation is well described, otherwise you can still ask questions.
Thank you!
Edit: I just saw a video and I had another idea to create a collection with the UID. This contains all categories as documents and the categories have a subcollection with all Todos.

Related

Firestore Rules - Array validation

I am using firestore for creating a food blog where users can upload posts and like it.
Call it facebook for food.
Below I will give you summary of 2 firestore database collections which are going to be used in my question.
First is Users - where the document name is based on UID and it stores information like, username/emailID
Second is Posts - where the document name is based on UID, however in the structure of the collection
It has a column named as "Likes" which is an array object. This stores 2 values : 1. Name of the person who liked the post and 2. UID of the person who liked the post.
Please find the structure of LIKES column in posts document below :
I am trying to add more validations to the likes part of the document.
However, from postman it is possible to change the name of the person who is liking the post.
The logic of the restrictions has to be on 2 things.
LIKES - UID should be present in my users collection. Also, UID in LIKES column shouldn't be changeable.
LIKES - Name should not be allowed to be changed.
I tried a of way of doing it but it doesnt work :
exists(/databases/$(database)/documents/users/$(request.resource.data.likes[request.resource.data.likes.size() -1].userId))
What it does is checks the last UID of person liking that document. However, in this scenario if there are more than 1 Likes, the name/uid could be altered for the ones which were present earlier.
Not a very efficient way.
Also, Loops dont work in rules so I cant loop it up to get it.
Any help would be really appreciated.
Please let me know if there are any more snippets which would be required.

How to handle custom user ordering in Firestore

From the context of a todo application, the user has a list of todos, if they reorder an item anywhere in the list how could that be saved in Firebase Firestore?
I currently have a collection with ALL todos. They get filtered by user ID and day, but I’d like to allow for custom ordering of todos. How could that be achieved?
In order to maintain the previous costs while also allowing todo items to be ordered per user you can utilize a new field per document in the todo collection. You can attempt to add a field, named lets say "order", which will hold the numerical value for the order of the todo element for each user. For example "0" for first position,"1" for second, and so on so forth. These will then be filtered by user ID and day as mentioned previously.
There is no inbuilt solution available for this. The solution I will suggest is to keep a separate document per user which maintains the order of documents (in this case to do items) in an array and when you show the data to the user in the UI, use the document to order the items on the page.
But keep in mind this approach will increase your database costs because you will need to perform an update to 2 documents whenever a new todo is created.

Is there a method to find the values of an array from a collection in a separate collection in Firestore?

I have two collections users and uploads. The user collection shows details about the users that have registered to the app. It contains details about the user such as name, userid and following which is an array. The following array contains list of people that the user is following as shown here.
The uploads collection has the posts that are made by the users. Each document in the uploads collection has details such as the postid, post and name of the user who posted it as shown here.
I want to get only the uploads made by the users whom they are following.
For example, Sally follows three people Sam, Thomas and Ellie. I want Sally to get only the uploads that
are made by either of these three people from the uploads collection. Any help would be appreciated. Thank You
I think this might be what you're looking for. You could fetch the users' following array and then use that array to fetch uploads containing people from the following. As a sidenote I'd recommend the userId instead of the name of the user as these might not be unique.

Saving users scores and favorites in Firestore Database

I am working in a small project that uses Firestore database as a backend. I explain about the database so it is understood what I need:
Basically I have a collection that contains a list of documents where each one of them represent a game. For each game I have the name, cover image, info, category, etc.
I also have a collection of the users, where I have the specific UID for each user (retrieved from the auth section), email, etc.
What I want now is to save the score that some user may have in some of these games, as well as the favorite games that the user could save. What I don't get to understand is how to create the connection between the users and the games. For example, I thought that I should save the users score creating a collection within each document(game) in the first collection that mentioned. But when I create this collection with ID "scores" it asks me for the first document where I have to facilitate an ID (if not automatic) and then I don't know how to proceed.
I have read also that I would have to create additional collections in the root folder like "favorites" or "scores" specifying the UID of the user but, how do I connect the user UID, the score, and game which the user got that score from?
I hope I explained myself properly. Thanks.
Firstly, I agree with Doug's comment above. The Firestore tutorial videos are a great resource!
In terms of connecting data to your user, you have some options. You can either:
Create sub-collections under each user. Such as /users/{user_id}/favorites. Favorites could be a sub-collection or an array of game_ids depending on your use case.
Store a userID field in the documents in a top level "scores" or "favorites" collection. Then you can query for scores in the /scores collection by adding a where userID == {user_id} clause to your query of the /scores collection.

Deleting data that all users use but only for one user in Cloud Firestore

I am trying to structure my data such that when someone adds a new product to the database, all users receive the new product in their list and therefore the new product appears on their screen.
But if a user decides to delete that product, they can delete it but only for themselves. Is there a Cloud Firestore sorting/ordering/filtering that I should be using to accomplish this?
I thought I could use something like the following:
final theProduct = Provider.of<Products>(context);
products = await firestore.collection('products').getDocuments()
for (product in products.documents) {
await firestore.collection('products').add({
'nameOfProduct': theProduct.nameOfProduct
});
}
But I get a document property error.
Maybe I need to go in one more collection and then try something? But I also need to be able to retrieve the data back using the userID of the signed in user..
Any hints/helpful links would be greatly appreciated.
So I think what I want to do is iterate through all documents within a collection and then document().collection('').add() something to each of their collection. Hopefully that sheds some more light on my problem.
Thanks to those who commented. I found a way to implement this was to use the unique value that each product contains and add it to a list on a per user basis in Firestore. Then fetch that list from Firestore and filter out the corresponding products. No deleting necessary.
Question : a user decides to delete that product, they can delete it but only for themselves
Answer: U can create list in user profile section where u can have all the product document ids & u can use that document id to fetch particular product details & when user click on delete button u can remove that particular document id from there collection
Im not sure what r u doing with sample code over there.
If u want to add data to database then use :
await Firestore().collection('Products').add({
'nameOfProduct': theProduct.nameOfProduct,
});
this will generate document random id for your product.
To get data from particular id use :
DocumentSnapshot documentSnapshot = await Firestore().collection('Products').document('document').get();
then u can use that document snapshot to get data for particular key e.g.
documentSnapshot.data['Product Name']

Resources