Firestore: Running Complex Update Queries With Multiple Retrievals (ReactJS)
I have a grid of data whose endpoints are displayed from data stored in my firestore database. So for instance an outline could be as follows:
| Spent total: $150 |
| Item 1: $80 |
| Item 2: $70 |
So the value for all of these costs (70,80 and 150) is stored in my firestore database with the sub items being a separate collection from my total spent. Now, I wannt to be able to update the price of item 2 to say $90 which will then update Item 2's value in firestore, but I want this to then run a check against the table so that the "spent total" is also updated to say "$170". What would be the best way to accomplish something like this?
Especially if I were to add multiple rows and columns that all are dependent on one another, what is the best way to update one part of my grid so that afterwords all of the data endpoints on the grid are updated correctly? Should I be using cloud functions somehow?
Additionally, I am creating a ReactJS app and previously in the app I just had my grid endpoints stored in my Redux store state so that I could run complex methods that checked each row and column and did some math to update each endpoint correctly, but what is the best way to do this now that I have migrated my data to firestore?
Edit:here are some pictures of how I am trying to set up my firestore layout currently:
reactjs firebase optimization google-cloud-firestore
add a comment |
I have a grid of data whose endpoints are displayed from data stored in my firestore database. So for instance an outline could be as follows:
| Spent total: $150 |
| Item 1: $80 |
| Item 2: $70 |
So the value for all of these costs (70,80 and 150) is stored in my firestore database with the sub items being a separate collection from my total spent. Now, I wannt to be able to update the price of item 2 to say $90 which will then update Item 2's value in firestore, but I want this to then run a check against the table so that the "spent total" is also updated to say "$170". What would be the best way to accomplish something like this?
Especially if I were to add multiple rows and columns that all are dependent on one another, what is the best way to update one part of my grid so that afterwords all of the data endpoints on the grid are updated correctly? Should I be using cloud functions somehow?
Additionally, I am creating a ReactJS app and previously in the app I just had my grid endpoints stored in my Redux store state so that I could run complex methods that checked each row and column and did some math to update each endpoint correctly, but what is the best way to do this now that I have migrated my data to firestore?
Edit:here are some pictures of how I am trying to set up my firestore layout currently:
reactjs firebase optimization google-cloud-firestore
add a comment |
I have a grid of data whose endpoints are displayed from data stored in my firestore database. So for instance an outline could be as follows:
| Spent total: $150 |
| Item 1: $80 |
| Item 2: $70 |
So the value for all of these costs (70,80 and 150) is stored in my firestore database with the sub items being a separate collection from my total spent. Now, I wannt to be able to update the price of item 2 to say $90 which will then update Item 2's value in firestore, but I want this to then run a check against the table so that the "spent total" is also updated to say "$170". What would be the best way to accomplish something like this?
Especially if I were to add multiple rows and columns that all are dependent on one another, what is the best way to update one part of my grid so that afterwords all of the data endpoints on the grid are updated correctly? Should I be using cloud functions somehow?
Additionally, I am creating a ReactJS app and previously in the app I just had my grid endpoints stored in my Redux store state so that I could run complex methods that checked each row and column and did some math to update each endpoint correctly, but what is the best way to do this now that I have migrated my data to firestore?
Edit:here are some pictures of how I am trying to set up my firestore layout currently:
reactjs firebase optimization google-cloud-firestore
I have a grid of data whose endpoints are displayed from data stored in my firestore database. So for instance an outline could be as follows:
| Spent total: $150 |
| Item 1: $80 |
| Item 2: $70 |
So the value for all of these costs (70,80 and 150) is stored in my firestore database with the sub items being a separate collection from my total spent. Now, I wannt to be able to update the price of item 2 to say $90 which will then update Item 2's value in firestore, but I want this to then run a check against the table so that the "spent total" is also updated to say "$170". What would be the best way to accomplish something like this?
Especially if I were to add multiple rows and columns that all are dependent on one another, what is the best way to update one part of my grid so that afterwords all of the data endpoints on the grid are updated correctly? Should I be using cloud functions somehow?
Additionally, I am creating a ReactJS app and previously in the app I just had my grid endpoints stored in my Redux store state so that I could run complex methods that checked each row and column and did some math to update each endpoint correctly, but what is the best way to do this now that I have migrated my data to firestore?
Edit:here are some pictures of how I am trying to set up my firestore layout currently:
reactjs firebase optimization google-cloud-firestore
reactjs firebase optimization google-cloud-firestore
edited Nov 18 '18 at 17:17
FrankTheTank
asked Nov 13 '18 at 23:19
FrankTheTankFrankTheTank
203315
203315
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
You might want to back up a little and get a better understanding of the type of database that Firestore is. It's NoSQL, so things like rows and columns and tables don't exist.
Try this video: https://youtu.be/v_hR4K4auoQ
and this one: https://youtu.be/haMOUb3KVSo
But yes, you could use a cloud function to update a value for you, or you could make the new Spent total calculation within your app logic and when you write the new value for Item 2, also write the new value for Spent total.
But mostly, you need to understand how firestore stores your data and how it charges you to retrieve it. You are mostly charged for each read/write request, with much less concern for the actual amount of data you have stored overall. So it will probably be better to NOT keep these values in separate collections if you are always going to be utilizing them at the same time.
For example:
Collection(transactions) => Document(transaction133453) item1: $80, item2: $70, spentTotal: $150
and then if you needed to update that transaction, you would just update the values for that document all at once and it would only count as 1 write operation. You could store the transactions collection as a subcollection of a customer document, or simply as its own collection. But the bottom line is most of the best practices you would rely on for a SQL database with tables, columns, and rows are 100% irrelevant for a Firestore (NoSQL) database, so you must have a full understanding of what that means before you start to plan the structure of your database.
I hope this helps!! Happy YouTubing...
Edit in response to comment:
The way I like to think about it is how am I going to use the data as opposed to what is the most logical way to organize the data. I'm not sure I understand the context of your example data, but if I were maybe tracking budgets for projects or something, I might use something like the screenshots I pasted below.
Since I am likely going to have a pretty limited number of team members for each budget, that can be stored in an array within the document, along with ALL of the fields specific to that budget - basically anything that I might like to show in a screen that displays budget details, for instance. Because when you make a query to populate the data for that screen, if everything you need is all in one document, then you only have to make one request! But if you kept your "headers" in one doc and then your "data" in another doc, now you have to make 2 requests just to populate 1 screen.
Then maybe on that screen, I have a link to "View Related Transactions", if the user clicks on that, you would then call a query to your collection of transactions. Something like transactions is best stored in a collection, because you probably don't know if you are going to have 5 transactions or 500. If you wanted to show how many total transactions you had on your budget details page, you might consider adding a field in your budget doc for "totalTransactions: (number)". Then each time a user added a transaction, you would write the transaction details to the appropriate transactions collection, and also increase the totalTransactions field by 1 - this would be 2 writes to your db. Firestore is built around the concept that users are likely reading data way more frequently than writing data. So make two writes when you update your transactions, but only have to read one doc every time you look at your budget and want to know how many transactions have taken place.
Same for something like chats. But you would only make chats a subcollection of the budget document if you wanted to only ever show chats for one budget at a time. If you wanted all your chats to be taking place in one screen to talk about all budgets, you would likely want to make your chats collection at the root level.
As for getting your data from the document, it's basically a JSON object so (may vary slightly depending on what kind of app you are working in),
a nested array is referred to by:
documentName.arrayName[index]
budget12345.teamMembers[1]
a nested object:
documentName.objectName.fieldName
budget12345.projectManager.firstName
And then a subcollection is
collection(budgets).document(budget12345).subcollection(transactions)
FirebaseExample budget doc
FirebaseExample remainder of budget doc
FirebaseExample team chats collection
FirebaseExample transactions collection
Hey Kat thanks for the response I have messed around with making my own firestore "schema" (I know its technically schema-less) just to see what would work best I will post some pictures above to show you what I have been working with. So Right now I have set up a lot of fields in my data document but I am also trying now to extrapolate all of that data down into more sub collections and documents. You are saying it would be better to keep all the data in one document correct to save on writes since it is costly? What about for grabbing all of the data in my arrays, that is proving difficult.
– FrankTheTank
Nov 18 '18 at 17:16
Hey Frank - I updated my answer with more detail. :)
– Kat
Nov 18 '18 at 18:47
Hey kat thanks a lot for the answer that helped a lot! So the only thing is if I have a lot of indices in my content array (field in my data document). What would be the best way to say update one index in the content array and then have that update all other indexes in the content array? Cause that is essentially what I am trying to do, wouldn't I have to do a write for each of those anyways so would it make more sense to just structure my data into sub collections and documents?
– FrankTheTank
Nov 18 '18 at 20:32
Or should I do something like grab all of the data from my document, run a function to calculate how to update everything and then update ALL of the json data in one transaction? Would it be best to do this with some sort of cloud functions or just in plain javascript. I am using ReactJS by the way and the react-redux-firebase and redux-firestore plugins so I am not sure if I could somehow tie my firestore data to my redux store.
– FrankTheTank
Nov 18 '18 at 20:35
It actually only counts as one write whether you are creating the entire document, replacing the entire contents of the document with new data, or replacing one or more fields individually on a document. So, the best way would be to create a javascript object representing your document in your react app.
– Kat
Nov 18 '18 at 22:10
|
show 5 more comments
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53290934%2ffirestore-running-complex-update-queries-with-multiple-retrievals-reactjs%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You might want to back up a little and get a better understanding of the type of database that Firestore is. It's NoSQL, so things like rows and columns and tables don't exist.
Try this video: https://youtu.be/v_hR4K4auoQ
and this one: https://youtu.be/haMOUb3KVSo
But yes, you could use a cloud function to update a value for you, or you could make the new Spent total calculation within your app logic and when you write the new value for Item 2, also write the new value for Spent total.
But mostly, you need to understand how firestore stores your data and how it charges you to retrieve it. You are mostly charged for each read/write request, with much less concern for the actual amount of data you have stored overall. So it will probably be better to NOT keep these values in separate collections if you are always going to be utilizing them at the same time.
For example:
Collection(transactions) => Document(transaction133453) item1: $80, item2: $70, spentTotal: $150
and then if you needed to update that transaction, you would just update the values for that document all at once and it would only count as 1 write operation. You could store the transactions collection as a subcollection of a customer document, or simply as its own collection. But the bottom line is most of the best practices you would rely on for a SQL database with tables, columns, and rows are 100% irrelevant for a Firestore (NoSQL) database, so you must have a full understanding of what that means before you start to plan the structure of your database.
I hope this helps!! Happy YouTubing...
Edit in response to comment:
The way I like to think about it is how am I going to use the data as opposed to what is the most logical way to organize the data. I'm not sure I understand the context of your example data, but if I were maybe tracking budgets for projects or something, I might use something like the screenshots I pasted below.
Since I am likely going to have a pretty limited number of team members for each budget, that can be stored in an array within the document, along with ALL of the fields specific to that budget - basically anything that I might like to show in a screen that displays budget details, for instance. Because when you make a query to populate the data for that screen, if everything you need is all in one document, then you only have to make one request! But if you kept your "headers" in one doc and then your "data" in another doc, now you have to make 2 requests just to populate 1 screen.
Then maybe on that screen, I have a link to "View Related Transactions", if the user clicks on that, you would then call a query to your collection of transactions. Something like transactions is best stored in a collection, because you probably don't know if you are going to have 5 transactions or 500. If you wanted to show how many total transactions you had on your budget details page, you might consider adding a field in your budget doc for "totalTransactions: (number)". Then each time a user added a transaction, you would write the transaction details to the appropriate transactions collection, and also increase the totalTransactions field by 1 - this would be 2 writes to your db. Firestore is built around the concept that users are likely reading data way more frequently than writing data. So make two writes when you update your transactions, but only have to read one doc every time you look at your budget and want to know how many transactions have taken place.
Same for something like chats. But you would only make chats a subcollection of the budget document if you wanted to only ever show chats for one budget at a time. If you wanted all your chats to be taking place in one screen to talk about all budgets, you would likely want to make your chats collection at the root level.
As for getting your data from the document, it's basically a JSON object so (may vary slightly depending on what kind of app you are working in),
a nested array is referred to by:
documentName.arrayName[index]
budget12345.teamMembers[1]
a nested object:
documentName.objectName.fieldName
budget12345.projectManager.firstName
And then a subcollection is
collection(budgets).document(budget12345).subcollection(transactions)
FirebaseExample budget doc
FirebaseExample remainder of budget doc
FirebaseExample team chats collection
FirebaseExample transactions collection
Hey Kat thanks for the response I have messed around with making my own firestore "schema" (I know its technically schema-less) just to see what would work best I will post some pictures above to show you what I have been working with. So Right now I have set up a lot of fields in my data document but I am also trying now to extrapolate all of that data down into more sub collections and documents. You are saying it would be better to keep all the data in one document correct to save on writes since it is costly? What about for grabbing all of the data in my arrays, that is proving difficult.
– FrankTheTank
Nov 18 '18 at 17:16
Hey Frank - I updated my answer with more detail. :)
– Kat
Nov 18 '18 at 18:47
Hey kat thanks a lot for the answer that helped a lot! So the only thing is if I have a lot of indices in my content array (field in my data document). What would be the best way to say update one index in the content array and then have that update all other indexes in the content array? Cause that is essentially what I am trying to do, wouldn't I have to do a write for each of those anyways so would it make more sense to just structure my data into sub collections and documents?
– FrankTheTank
Nov 18 '18 at 20:32
Or should I do something like grab all of the data from my document, run a function to calculate how to update everything and then update ALL of the json data in one transaction? Would it be best to do this with some sort of cloud functions or just in plain javascript. I am using ReactJS by the way and the react-redux-firebase and redux-firestore plugins so I am not sure if I could somehow tie my firestore data to my redux store.
– FrankTheTank
Nov 18 '18 at 20:35
It actually only counts as one write whether you are creating the entire document, replacing the entire contents of the document with new data, or replacing one or more fields individually on a document. So, the best way would be to create a javascript object representing your document in your react app.
– Kat
Nov 18 '18 at 22:10
|
show 5 more comments
You might want to back up a little and get a better understanding of the type of database that Firestore is. It's NoSQL, so things like rows and columns and tables don't exist.
Try this video: https://youtu.be/v_hR4K4auoQ
and this one: https://youtu.be/haMOUb3KVSo
But yes, you could use a cloud function to update a value for you, or you could make the new Spent total calculation within your app logic and when you write the new value for Item 2, also write the new value for Spent total.
But mostly, you need to understand how firestore stores your data and how it charges you to retrieve it. You are mostly charged for each read/write request, with much less concern for the actual amount of data you have stored overall. So it will probably be better to NOT keep these values in separate collections if you are always going to be utilizing them at the same time.
For example:
Collection(transactions) => Document(transaction133453) item1: $80, item2: $70, spentTotal: $150
and then if you needed to update that transaction, you would just update the values for that document all at once and it would only count as 1 write operation. You could store the transactions collection as a subcollection of a customer document, or simply as its own collection. But the bottom line is most of the best practices you would rely on for a SQL database with tables, columns, and rows are 100% irrelevant for a Firestore (NoSQL) database, so you must have a full understanding of what that means before you start to plan the structure of your database.
I hope this helps!! Happy YouTubing...
Edit in response to comment:
The way I like to think about it is how am I going to use the data as opposed to what is the most logical way to organize the data. I'm not sure I understand the context of your example data, but if I were maybe tracking budgets for projects or something, I might use something like the screenshots I pasted below.
Since I am likely going to have a pretty limited number of team members for each budget, that can be stored in an array within the document, along with ALL of the fields specific to that budget - basically anything that I might like to show in a screen that displays budget details, for instance. Because when you make a query to populate the data for that screen, if everything you need is all in one document, then you only have to make one request! But if you kept your "headers" in one doc and then your "data" in another doc, now you have to make 2 requests just to populate 1 screen.
Then maybe on that screen, I have a link to "View Related Transactions", if the user clicks on that, you would then call a query to your collection of transactions. Something like transactions is best stored in a collection, because you probably don't know if you are going to have 5 transactions or 500. If you wanted to show how many total transactions you had on your budget details page, you might consider adding a field in your budget doc for "totalTransactions: (number)". Then each time a user added a transaction, you would write the transaction details to the appropriate transactions collection, and also increase the totalTransactions field by 1 - this would be 2 writes to your db. Firestore is built around the concept that users are likely reading data way more frequently than writing data. So make two writes when you update your transactions, but only have to read one doc every time you look at your budget and want to know how many transactions have taken place.
Same for something like chats. But you would only make chats a subcollection of the budget document if you wanted to only ever show chats for one budget at a time. If you wanted all your chats to be taking place in one screen to talk about all budgets, you would likely want to make your chats collection at the root level.
As for getting your data from the document, it's basically a JSON object so (may vary slightly depending on what kind of app you are working in),
a nested array is referred to by:
documentName.arrayName[index]
budget12345.teamMembers[1]
a nested object:
documentName.objectName.fieldName
budget12345.projectManager.firstName
And then a subcollection is
collection(budgets).document(budget12345).subcollection(transactions)
FirebaseExample budget doc
FirebaseExample remainder of budget doc
FirebaseExample team chats collection
FirebaseExample transactions collection
Hey Kat thanks for the response I have messed around with making my own firestore "schema" (I know its technically schema-less) just to see what would work best I will post some pictures above to show you what I have been working with. So Right now I have set up a lot of fields in my data document but I am also trying now to extrapolate all of that data down into more sub collections and documents. You are saying it would be better to keep all the data in one document correct to save on writes since it is costly? What about for grabbing all of the data in my arrays, that is proving difficult.
– FrankTheTank
Nov 18 '18 at 17:16
Hey Frank - I updated my answer with more detail. :)
– Kat
Nov 18 '18 at 18:47
Hey kat thanks a lot for the answer that helped a lot! So the only thing is if I have a lot of indices in my content array (field in my data document). What would be the best way to say update one index in the content array and then have that update all other indexes in the content array? Cause that is essentially what I am trying to do, wouldn't I have to do a write for each of those anyways so would it make more sense to just structure my data into sub collections and documents?
– FrankTheTank
Nov 18 '18 at 20:32
Or should I do something like grab all of the data from my document, run a function to calculate how to update everything and then update ALL of the json data in one transaction? Would it be best to do this with some sort of cloud functions or just in plain javascript. I am using ReactJS by the way and the react-redux-firebase and redux-firestore plugins so I am not sure if I could somehow tie my firestore data to my redux store.
– FrankTheTank
Nov 18 '18 at 20:35
It actually only counts as one write whether you are creating the entire document, replacing the entire contents of the document with new data, or replacing one or more fields individually on a document. So, the best way would be to create a javascript object representing your document in your react app.
– Kat
Nov 18 '18 at 22:10
|
show 5 more comments
You might want to back up a little and get a better understanding of the type of database that Firestore is. It's NoSQL, so things like rows and columns and tables don't exist.
Try this video: https://youtu.be/v_hR4K4auoQ
and this one: https://youtu.be/haMOUb3KVSo
But yes, you could use a cloud function to update a value for you, or you could make the new Spent total calculation within your app logic and when you write the new value for Item 2, also write the new value for Spent total.
But mostly, you need to understand how firestore stores your data and how it charges you to retrieve it. You are mostly charged for each read/write request, with much less concern for the actual amount of data you have stored overall. So it will probably be better to NOT keep these values in separate collections if you are always going to be utilizing them at the same time.
For example:
Collection(transactions) => Document(transaction133453) item1: $80, item2: $70, spentTotal: $150
and then if you needed to update that transaction, you would just update the values for that document all at once and it would only count as 1 write operation. You could store the transactions collection as a subcollection of a customer document, or simply as its own collection. But the bottom line is most of the best practices you would rely on for a SQL database with tables, columns, and rows are 100% irrelevant for a Firestore (NoSQL) database, so you must have a full understanding of what that means before you start to plan the structure of your database.
I hope this helps!! Happy YouTubing...
Edit in response to comment:
The way I like to think about it is how am I going to use the data as opposed to what is the most logical way to organize the data. I'm not sure I understand the context of your example data, but if I were maybe tracking budgets for projects or something, I might use something like the screenshots I pasted below.
Since I am likely going to have a pretty limited number of team members for each budget, that can be stored in an array within the document, along with ALL of the fields specific to that budget - basically anything that I might like to show in a screen that displays budget details, for instance. Because when you make a query to populate the data for that screen, if everything you need is all in one document, then you only have to make one request! But if you kept your "headers" in one doc and then your "data" in another doc, now you have to make 2 requests just to populate 1 screen.
Then maybe on that screen, I have a link to "View Related Transactions", if the user clicks on that, you would then call a query to your collection of transactions. Something like transactions is best stored in a collection, because you probably don't know if you are going to have 5 transactions or 500. If you wanted to show how many total transactions you had on your budget details page, you might consider adding a field in your budget doc for "totalTransactions: (number)". Then each time a user added a transaction, you would write the transaction details to the appropriate transactions collection, and also increase the totalTransactions field by 1 - this would be 2 writes to your db. Firestore is built around the concept that users are likely reading data way more frequently than writing data. So make two writes when you update your transactions, but only have to read one doc every time you look at your budget and want to know how many transactions have taken place.
Same for something like chats. But you would only make chats a subcollection of the budget document if you wanted to only ever show chats for one budget at a time. If you wanted all your chats to be taking place in one screen to talk about all budgets, you would likely want to make your chats collection at the root level.
As for getting your data from the document, it's basically a JSON object so (may vary slightly depending on what kind of app you are working in),
a nested array is referred to by:
documentName.arrayName[index]
budget12345.teamMembers[1]
a nested object:
documentName.objectName.fieldName
budget12345.projectManager.firstName
And then a subcollection is
collection(budgets).document(budget12345).subcollection(transactions)
FirebaseExample budget doc
FirebaseExample remainder of budget doc
FirebaseExample team chats collection
FirebaseExample transactions collection
You might want to back up a little and get a better understanding of the type of database that Firestore is. It's NoSQL, so things like rows and columns and tables don't exist.
Try this video: https://youtu.be/v_hR4K4auoQ
and this one: https://youtu.be/haMOUb3KVSo
But yes, you could use a cloud function to update a value for you, or you could make the new Spent total calculation within your app logic and when you write the new value for Item 2, also write the new value for Spent total.
But mostly, you need to understand how firestore stores your data and how it charges you to retrieve it. You are mostly charged for each read/write request, with much less concern for the actual amount of data you have stored overall. So it will probably be better to NOT keep these values in separate collections if you are always going to be utilizing them at the same time.
For example:
Collection(transactions) => Document(transaction133453) item1: $80, item2: $70, spentTotal: $150
and then if you needed to update that transaction, you would just update the values for that document all at once and it would only count as 1 write operation. You could store the transactions collection as a subcollection of a customer document, or simply as its own collection. But the bottom line is most of the best practices you would rely on for a SQL database with tables, columns, and rows are 100% irrelevant for a Firestore (NoSQL) database, so you must have a full understanding of what that means before you start to plan the structure of your database.
I hope this helps!! Happy YouTubing...
Edit in response to comment:
The way I like to think about it is how am I going to use the data as opposed to what is the most logical way to organize the data. I'm not sure I understand the context of your example data, but if I were maybe tracking budgets for projects or something, I might use something like the screenshots I pasted below.
Since I am likely going to have a pretty limited number of team members for each budget, that can be stored in an array within the document, along with ALL of the fields specific to that budget - basically anything that I might like to show in a screen that displays budget details, for instance. Because when you make a query to populate the data for that screen, if everything you need is all in one document, then you only have to make one request! But if you kept your "headers" in one doc and then your "data" in another doc, now you have to make 2 requests just to populate 1 screen.
Then maybe on that screen, I have a link to "View Related Transactions", if the user clicks on that, you would then call a query to your collection of transactions. Something like transactions is best stored in a collection, because you probably don't know if you are going to have 5 transactions or 500. If you wanted to show how many total transactions you had on your budget details page, you might consider adding a field in your budget doc for "totalTransactions: (number)". Then each time a user added a transaction, you would write the transaction details to the appropriate transactions collection, and also increase the totalTransactions field by 1 - this would be 2 writes to your db. Firestore is built around the concept that users are likely reading data way more frequently than writing data. So make two writes when you update your transactions, but only have to read one doc every time you look at your budget and want to know how many transactions have taken place.
Same for something like chats. But you would only make chats a subcollection of the budget document if you wanted to only ever show chats for one budget at a time. If you wanted all your chats to be taking place in one screen to talk about all budgets, you would likely want to make your chats collection at the root level.
As for getting your data from the document, it's basically a JSON object so (may vary slightly depending on what kind of app you are working in),
a nested array is referred to by:
documentName.arrayName[index]
budget12345.teamMembers[1]
a nested object:
documentName.objectName.fieldName
budget12345.projectManager.firstName
And then a subcollection is
collection(budgets).document(budget12345).subcollection(transactions)
FirebaseExample budget doc
FirebaseExample remainder of budget doc
FirebaseExample team chats collection
FirebaseExample transactions collection
edited Nov 18 '18 at 18:45
answered Nov 17 '18 at 23:25
KatKat
866
866
Hey Kat thanks for the response I have messed around with making my own firestore "schema" (I know its technically schema-less) just to see what would work best I will post some pictures above to show you what I have been working with. So Right now I have set up a lot of fields in my data document but I am also trying now to extrapolate all of that data down into more sub collections and documents. You are saying it would be better to keep all the data in one document correct to save on writes since it is costly? What about for grabbing all of the data in my arrays, that is proving difficult.
– FrankTheTank
Nov 18 '18 at 17:16
Hey Frank - I updated my answer with more detail. :)
– Kat
Nov 18 '18 at 18:47
Hey kat thanks a lot for the answer that helped a lot! So the only thing is if I have a lot of indices in my content array (field in my data document). What would be the best way to say update one index in the content array and then have that update all other indexes in the content array? Cause that is essentially what I am trying to do, wouldn't I have to do a write for each of those anyways so would it make more sense to just structure my data into sub collections and documents?
– FrankTheTank
Nov 18 '18 at 20:32
Or should I do something like grab all of the data from my document, run a function to calculate how to update everything and then update ALL of the json data in one transaction? Would it be best to do this with some sort of cloud functions or just in plain javascript. I am using ReactJS by the way and the react-redux-firebase and redux-firestore plugins so I am not sure if I could somehow tie my firestore data to my redux store.
– FrankTheTank
Nov 18 '18 at 20:35
It actually only counts as one write whether you are creating the entire document, replacing the entire contents of the document with new data, or replacing one or more fields individually on a document. So, the best way would be to create a javascript object representing your document in your react app.
– Kat
Nov 18 '18 at 22:10
|
show 5 more comments
Hey Kat thanks for the response I have messed around with making my own firestore "schema" (I know its technically schema-less) just to see what would work best I will post some pictures above to show you what I have been working with. So Right now I have set up a lot of fields in my data document but I am also trying now to extrapolate all of that data down into more sub collections and documents. You are saying it would be better to keep all the data in one document correct to save on writes since it is costly? What about for grabbing all of the data in my arrays, that is proving difficult.
– FrankTheTank
Nov 18 '18 at 17:16
Hey Frank - I updated my answer with more detail. :)
– Kat
Nov 18 '18 at 18:47
Hey kat thanks a lot for the answer that helped a lot! So the only thing is if I have a lot of indices in my content array (field in my data document). What would be the best way to say update one index in the content array and then have that update all other indexes in the content array? Cause that is essentially what I am trying to do, wouldn't I have to do a write for each of those anyways so would it make more sense to just structure my data into sub collections and documents?
– FrankTheTank
Nov 18 '18 at 20:32
Or should I do something like grab all of the data from my document, run a function to calculate how to update everything and then update ALL of the json data in one transaction? Would it be best to do this with some sort of cloud functions or just in plain javascript. I am using ReactJS by the way and the react-redux-firebase and redux-firestore plugins so I am not sure if I could somehow tie my firestore data to my redux store.
– FrankTheTank
Nov 18 '18 at 20:35
It actually only counts as one write whether you are creating the entire document, replacing the entire contents of the document with new data, or replacing one or more fields individually on a document. So, the best way would be to create a javascript object representing your document in your react app.
– Kat
Nov 18 '18 at 22:10
Hey Kat thanks for the response I have messed around with making my own firestore "schema" (I know its technically schema-less) just to see what would work best I will post some pictures above to show you what I have been working with. So Right now I have set up a lot of fields in my data document but I am also trying now to extrapolate all of that data down into more sub collections and documents. You are saying it would be better to keep all the data in one document correct to save on writes since it is costly? What about for grabbing all of the data in my arrays, that is proving difficult.
– FrankTheTank
Nov 18 '18 at 17:16
Hey Kat thanks for the response I have messed around with making my own firestore "schema" (I know its technically schema-less) just to see what would work best I will post some pictures above to show you what I have been working with. So Right now I have set up a lot of fields in my data document but I am also trying now to extrapolate all of that data down into more sub collections and documents. You are saying it would be better to keep all the data in one document correct to save on writes since it is costly? What about for grabbing all of the data in my arrays, that is proving difficult.
– FrankTheTank
Nov 18 '18 at 17:16
Hey Frank - I updated my answer with more detail. :)
– Kat
Nov 18 '18 at 18:47
Hey Frank - I updated my answer with more detail. :)
– Kat
Nov 18 '18 at 18:47
Hey kat thanks a lot for the answer that helped a lot! So the only thing is if I have a lot of indices in my content array (field in my data document). What would be the best way to say update one index in the content array and then have that update all other indexes in the content array? Cause that is essentially what I am trying to do, wouldn't I have to do a write for each of those anyways so would it make more sense to just structure my data into sub collections and documents?
– FrankTheTank
Nov 18 '18 at 20:32
Hey kat thanks a lot for the answer that helped a lot! So the only thing is if I have a lot of indices in my content array (field in my data document). What would be the best way to say update one index in the content array and then have that update all other indexes in the content array? Cause that is essentially what I am trying to do, wouldn't I have to do a write for each of those anyways so would it make more sense to just structure my data into sub collections and documents?
– FrankTheTank
Nov 18 '18 at 20:32
Or should I do something like grab all of the data from my document, run a function to calculate how to update everything and then update ALL of the json data in one transaction? Would it be best to do this with some sort of cloud functions or just in plain javascript. I am using ReactJS by the way and the react-redux-firebase and redux-firestore plugins so I am not sure if I could somehow tie my firestore data to my redux store.
– FrankTheTank
Nov 18 '18 at 20:35
Or should I do something like grab all of the data from my document, run a function to calculate how to update everything and then update ALL of the json data in one transaction? Would it be best to do this with some sort of cloud functions or just in plain javascript. I am using ReactJS by the way and the react-redux-firebase and redux-firestore plugins so I am not sure if I could somehow tie my firestore data to my redux store.
– FrankTheTank
Nov 18 '18 at 20:35
It actually only counts as one write whether you are creating the entire document, replacing the entire contents of the document with new data, or replacing one or more fields individually on a document. So, the best way would be to create a javascript object representing your document in your react app.
– Kat
Nov 18 '18 at 22:10
It actually only counts as one write whether you are creating the entire document, replacing the entire contents of the document with new data, or replacing one or more fields individually on a document. So, the best way would be to create a javascript object representing your document in your react app.
– Kat
Nov 18 '18 at 22:10
|
show 5 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53290934%2ffirestore-running-complex-update-queries-with-multiple-retrievals-reactjs%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown