Firestore clients and invoices, amended requirement - android

This question is a follow up question to the one posted here:
Firestore: Clients and invoices, how to model it
I am trying to understand the thought process behind modelling evolving requirements in Firebase/Firestore.
Assuming the accepted answer was used for the model, then 2 months you get a new requirement after the app has been released. Now the requirement says:
We need to get the invoice detail (not only id but the full details) for user whose last name is xyz.
How can model this assuming the database/app has been live for 2 months (so there is data in there already). The last name is already an attribute of the user details.
Thank you

According to the requirements that we see in this post, which I understand are mandatory in your project:
Show invoices that a client has
and
Update all invoices in the system to false
The most appropriate schema that can I recommend you, is the one in which you should add a new property called userId, beneath each invoice object.
So please consider using this tehnique, which is actually called a the reverse lookup. It will help you query your database more easily and will also help you solve both problems.

Related

How to handle foreign key kind of situation in google Firestore?

As there is no functionality of foreign Key in Firestore like that of MYSQL, so I am not able to replicate one of my important functionality that is to update a file in one place and it will reflect in every place. Also, Firebase has no functionality to update all the document's specific filed at once.
There are already these kinds of questions but I could not get my solution. Suppose I have a million documents containing a filed which is the density of a material. Later on, I found that my density value was wrong so how to update that value in all documents efficiently. Also, I do not want to use server/admin SDK.
If you need to change the contents of 1 million documents, then you will need to query for those 1 million documents, iterate the results, then update each of those 1 million documents individually.
There is no equivalent of a sql "update where" statement that updates multiple documents in one query. It requires one update per document.
If don't want to use the Admin SDK, then the option that you have is to update the value of your densityMaterial property on the client, which might not be the best solution. However, if you can divide the update operation in smaller chunks, you might succeed.
If you are using a POJO class to map each document, then you might be interested in my answer from the following post:
How to update one field from all documents using POJO in Firestore?
And if you are not using a POJO class, please check my answer from the following post:
Firestore firebase Android search and update query
Regarding the cost, you'll be billed with one write operation for every document that is updated. If all 1 MIL documents will be updated, then you'll be billed with 1 MIL write operations.
Edit:
Suppose I have a million documents containing a filed which is the density of a material. Later on, I found that my density value was wrong so how to update that value in all documents efficiently.
If all of those 1 MIL documents contain a property called densityMaterial, that holds the exact same value, it doesn't make any sense to store that property within each document. You can create a single document that contains that particular value, and in each and every document of those 1 MIL, simply add only a reference to that document. A DocumentReference is a supported data-type. Now, if you need to change that value, it will incur only a single document write.
However, if you have different values for the densityMaterial property and all of them are wrong, then you don't have a problem with the database, you have a problem with the mechanism/people that are adding data. It's not a matter of a database problem if you have added 1 MIL incorrect documents.
Why not chose MySQL?
MySQL cannot scale in the way Cloud Firestore does. Firestore simply scales massively.
Can I avoid this problem anyhow?
Yes, you can buy using a single document for such details.

Editing a Document based on query result in Firestore Transaction

I am currently doing a project on Firestore database with Android SDK. I need to write a Transaction, in which I want to edit a "destination" document in "destinations" collection, only when another collection named "batches" does not have any document with its field name "destionId" set to the editing destination document ID. I am checking that with a query with .limit(1) set
Now, I want to do this in a Transaction since this app is real time and will be used by so many people at the same time. If I did not use transaction, then the possibility is that another person may add a "batch" document with this destinationId right between my query for checking and actual editing of the destination document. So, I want to run the query and check batches collection every time the transaction retries.
But I'm not sure how to run the Firestore query inside the transaction as its asynchronous. I believe that there is no way to make a blocking query request in Android SDK. please correct me if wrong.
Can someone help me with an idea of how to resolve this conflict? Thanks in advance.
You can't perform a query inside a transaction, or make a transaction contingent on an unchanging set of query results. You can only fetch individual documents by their ID, with the intent to change them later in that transaction.
In case it's helpful to others, running a transaction that operates on a query result is possible via the admin SDK (in contrast to the Java client-side SDK). Check out the doc on this here.
Retrieve a document or a query result from the database. Holds a pessimistic lock on all returned documents.
This capability is also mentioned in the SO post here. Notice that on the corresponding client-side JS SDK doc, the argument to the get function only accepts a documentRef.

ANDROID FIRESTORE : get all the documents that has "current user" in it's sub collection [duplicate]

This question already has an answer here:
How to query a Firestore collection using a property from a step deeper with Kotlin? [duplicate]
(1 answer)
Closed 4 years ago.
I am new to Firestore cloud and I am trying to learn about it.
I am trying to build a project and I am stuck at one point.
My Firestore database looks like this:
enter image description here
enter image description here
I have a Groups collection that has "Users List" Sub-collection" where I have "timestamp" and "user_id".
When I created a group I grabbed the user_id of the "user" that creates a group and added that in "Users List".
Now I am looking to retrieve all the "Groups"(groupName) that the "CurrentUser" is involved in, and I am having hard time to figure it out because I found that NoSQL databases are very different from SQL databases.
Would be great if someone can shed a light on this matter.
Thank you
I'm not sure about this, but I think your best bet is to add some field to collect group that each user involve in "Users" Collection using array or object to collect it since Firestore can collect array or object.
But TBH, I not sure this is the best, but it is the best I can think rightnow. Because with these you only need to query 1 time for each user that you want to get usergroup and it help you to not use lots of query to get usergroups for each user. But it will couse you some additional size. But it still fine since Firestore costing is base on both query and size for this case. Little(?) additional data is better than waste lots of query to get usergroup for only one user.

Firebase database structure - storing user activity in order to customize views and permission

Working with Firebase for the first time and looking for advice of setting up the right structure for my project which is basically an "offers/coupon" type starter project.
The scenario is this:
I have a node containing a list of all offers available to users
This list of offers is displayed to users after successful Firebase authentication
When a user redeems an offer, I want to be able to count/record that activity in their child node under user and hide that offer so that they cannot see it again once used.
My question is what would be the best way to do this given that offers may be added, may expire, or may change at some point in the future. So, in effect, the user should receive the list of most updated offers, minus the ones he/she have used in the past.
a) would it be more effective to have a master list of offers, and then run a cloud/server function to clone this list for each new user an track that way
Firebase Structure 1
or
b) Keep a master list of offers in one node, then track user specific offer usage
Firebase Structure 2
Appreciate your guidance
The second solution is better because you'll save bandwith. This practice is called denormalization and is a common practice when it comes to Firebase. The first solution is not good becase every time you want to display the users you donwload unnecessary data. If you want to read more details about how you can structure a Firebase database in a efficient way, please read this post, Structuring your Firebase Data correctly for a Complex App. Also, you can take a look a this tutorial, Denormalization is normal with the Firebase Database, for a better understanding.
Second solution is much good. Because in first one we are having redundancy of data in our database. And second one obviously removing that cause.
But instead of using true or false because it is only showing you, "it's available or not", so you can use a string type parameter as "expired", "going to expire" and "updated" or whatever sooo. So it. Will be able to trace all you information related to offer for particular user. I think this is your requirement also.
Happy coding.

How to match elements from one set to elements in another set using Firebase?

I recently started to learn Android and I came across a problem. I want to create a code for Firebase (the database I am using to store values) such that the contents from one set are matched to elements in another set.
The scenario is as follows: there is a student who wants to learn or is interested in learning a new skill (C/C++, drawing, music, etc.), if he were to update them in their profile, he should get suggestions as names of other users registered in the application who have already listed their skill set.
It is much like how Facebook suggests common friends, but here, the basis for suggestion is what skills the user has and what he wants to learn.
I worked on the same thing for one of my apps. I'll write about what I did to achieve that
First of all, you need to design your Realtime Database structure in a way to achieve that.
Example of a Individual User node in your database at firebase could be like
User
- Personal Details
- First name
- last name
- Dob
- Interests (values like "music,movies,sports") //Separated by a comma
- ...
Now lets say User A likes "music" and that you need to suggest him other users who likes music too, In this case what you can do is retrieve all the users who have interests "music" in their profile.
reference.addChildEventListener()
In here,inside the onChildAdded() you can compare to see if the Interest of a particular user has music in it. (if it does, add that user to your arraylist for your recyclerview to display it.)
Hope it helps!

Categories

Resources