how to maintain duplicate data between documents sync on firebase? - firebase

I have a question about firestore and cloud function.
let say i have 2 collection:
products and reuse_shopping_carts.
and my reuse_shopping_cart document contain many products with all it’s properties (id,name,price,href).
now i want that if i change the price of a specific product in products collection , a cloud function will run on all reuse_shopping_cart documents and in every document that contains the specific product it will change is price.
someone can explain me how?
or what is the right approach to do it?
i know i can store in the reuse_shopping_cart only the product id and fetch the updated product data at client, but for a list of 100 product in one reuse_shopping_cart it’s will require 100 separate query for every time i want to read the shopping list, and changing price of a product is mach more rare, so i think it’s a better approach.
if you think differently i will happy to hear...
thank you!

You can structure your reuse_shopping_carts document like this:
products: (map)
(product id)
name:
value:
For example:
Then to find which documents to update when the price changes you can query like this:
firebase.firestore().collection('reuse_shopping_carts').where(`products.${productId}.price`, '>=', 0)

Related

What's the ideal data modeling for app with multi-filters?

Viewed the Firestore docs + Google's I/O 2019 webinar, but I'm still not clear about the right data modeling for my particular use case.
App lets pro service providers register and publish one or more of their services in pre-defined categories (Stay, Sports, Wellness...) and at pre-defined price points (50$, 75$, 100$...).
Users on the homepage are to filter down first with a price point slider - see wireframe), e.g: 199€, then and optionally by selecting the category, eg: all 'Sports' (at 199€) and the location (e.g: all sports at 199€ in the UK). Optionally because users can also build their list with a button as soon as the price is selected. The same 'build list' button is after the category selection and after the location selection. So 3 depths of filtering are possible.
What would be the ideal data structure, given that I want to avoid thousands of reads each time there's filtering.
Three root-level collections (service providers, price points, service categories?) with their relevant documents? I understand and accept denormalization for the purpose of my filtering.
Here's the wireframe for a better understanding of the filtering:
App lets pro service providers register and publish one or more of their services in pre-defined categories (Stay, Sports, Wellness...) and at pre-defined price points (50$, 75$, 100$...).
Since you're having pre-defined categories, prices, and locations, then the simplest solution for modeling such a database would be to have a single collection of products:
Firestore-root
|
--- products (collection)
|
--- $productId (document)
|
--- name: "Running Shoe"
|
--- category: "Sport"
|
--- price: 199
|
--- location: "Europe"
|
--- country: "France"
In this way, you can simply perform all queries that you need. Since you didn't specify a programming language, I'll write the queries in Java, but you can simply convert them into any other programming language. So for example, you can query all products with a particular price:
FirebaseFirestore db = FirebaseFirestore.getInstance();
Query queryByPrice = db.collection("products").whereEqualTo("price", 199);
If you need to query by price, category and location, then you have to chain multiple whereEqualTo() methods:
Query queryByPrice = db.collection("products")
.whereEqualTo("price", 199)
.whereEqualTo("category", "Sport")
.whereEqualTo("location", "Europe");
If you, however, need to order the results, ascending or descending, don't also forget to create an index.
What would be the ideal data structure, given that I want to avoid thousands of reads each time there's filtering.
If you don't need to have all the results at once, then you have to implement pagination. If you need to know the number of products that exist in the sports category ahead of time, that is not possible without performing a query and counting the available products. I have written an article regarding this topic called:
How to count the number of documents in a Firestore collection?
Another feasible possible solution would be to create a single document that contains all those numbers. In other words, exactly what you're displaying to the users, everything that exists in those screenshots. In this way, you'll only have to pay a single read operation. When the users click on a particular category, only then you should perform the actual search.
I understand and accept denormalization for the purpose of my filtering.
In this case, there is no need to denormalize the data. For more info regarding this kind of operation, please check my answer below:
What is denormalization in Firebase Cloud Firestore?

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

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.

How to get documents from Firestore without a single document id

So i have a collection named products in my Firestore and it contains all my products.
Since i am using Tag widget it gives me an error when there is more than one item sharing the same tag. So for my Products Builder i want to give a list that contains all my products without a specific product catched by his id, so stream property of my Stream Builder can be like this.
StreamBuilder(stream: Firestore.instance.collection('products').WITHOUT SPECIFIC PRODUCT ID .snapshot()
builder:...)
How can i do that?
It's not possible to construct a query for all documents except one. There are no inequality filters in Firestore.
Since it's just one document, it makes sense to simply do the query for all documents, the have the client code remove the one you don't want from the result set.

How to update a few properties of many documents in CosmosDB/DocumentDB when another property change?

I have a shopping cart document and a list of products that the customer has added to the shopping cart. These documents live in the CosmosDB.
{
"customer":"1000",
"products":[
{
"Product":"2000",
"Name":"iPhone 10"
}
]
}
There is another document which has the details of the product 2000. Often the name of the product are updated. For example, the name can be changed to iPhone 10 from Apple. As result of that change, the product name in the shopping cart also need to be changed to reflect the change.
How can I update the shopping cart documents of many customers with the new pdocut name efficiently?
I think you need to re-look at the way you are saving the documents.It is really not optimal solution
I would recommend you to store everything in a single document with nested arrays. Here is a great example on How to model and partition data on Azure Cosmos DB using a real-world example
Firstly,i have to say that your data is so closely related that you should use relational database. Cosmos DB SQL API is a non-relational database, and the relationship between data is relatively loose. It's tough to change the data of other columns as one column changes.
Since your plan has been decided already, you need to update all the related other data which contains product name column if the product name changes. Or you could consider adjusting your data structure. For example, if product name will be changed continuously,you could save the product info as the main of data and the shopping cart info as sub-nested array in the product.
Like:
{
"productId":"1",
"Name":"iphone",
"shopping cart":[
{
"customerId":"1000",
"count":"1"
},
{
"customerId":"2000",
"count":"2"
}
]
}

How can I make sure to fetch only the x most recent posts in DB?

I am trying to fiigure out how exacly I should make sure that I only fetch the most recent x posts from the DB.
My current fetch methods work as follows:
GetPeopleIFollowAnd loop over each UID
For each UID fetch his posts
By doing this however I cant efficiently (quickly) fetch only the most recent x posts. How can I do this?
Some possible ideas I have:
Create a new Node which, every time that one of your followers makes a post, they will be added beneath your UID with a timeStamp. So When I fetch I loop through this FollowersWhoCreatedRecently for each UID and only do so for the first 10
Problems I see with the above solution is that if a user were to have a millions of people following them this would be horribly slow when it comes to updating every single one of those million
I have found this which seems like it may be of use. How could I use this?
My DB structure for posts is as follows
Post
UID
postID
Media
media
image: URL
Based in a follower structure like:
WhoFollowsMeNode/UID/uid: true
I would have to, every time a user posts, loop through this list where for each user I would add the post to there timeLine... That seems undoable, and yet that what it seems they are doing here.
On Realtime Database, you can make use of limitToLast() method, you can then pass how many elements you want to bring, this method will fetch the last information that has been added in a node, since the documents are ordered with a timestamp, if you fetch them with limitToLast(10) you can get the last 10 posts of a user.
If you are working with a List of posts, you can invert the list when showing it to the user, doing this, you will see the most recent data first and the old data below.

Resources