Background
I'm a young developer still in my undergraduate program so I apologize in advance if I seem ignorant. I am, I'm learning and this solution is testing my abilities. It's fun though hopefully, I can get some help.
Goal
I need to update every document within one of my Firestore collections. Each document needs additional data from its corresponding user document.
For example: The document that needs to be updated contains "John" and "Amanda" 's uids. I need to add additional fields to their shared document that is each of their "FullName": "John Adams" and "Amanda Smith"
Before Update:
{
"Document"
"userA": "John",
"userB": "Amanda"
}
After Update:
{
"Document"
"userA": "John",
"userAFull": "John Adams",
"userB": "Amanda",
"userBFull": "Amanda Smith"
}
Approach
Since I have to update every document within the collection (Approx 20k documents) I decided to write a Cloud Function using chained batched writes to solve this problem so that all the requests do not have to go through the Firestore API, like the client reads and writes.
Here is the material I have referenced when creating my function:
Get Data From Single Document Firestore Typescript
Returning multiple values in Tpyescript
Firestore Batched writes documentation
Here is my code that has errors:
export const updateFollowersSchema = functions
.runWith({ timeoutSeconds: 600 })
.https.onRequest(async (req,res) => {
const query = await db.collection('Followers')
query.get()
.then(query => {
if (query.empty){
return null;
} else {
const batchArray: any[] = []
batchArray.push(db.batch())
let operationCounter = 0;
let batchIndex = 0;
query.forEach(async document => {
const fromUserFullname = await getFromInfo(document)
const [forUserFullname, forUserProfileImageURL] = await getForInfo(document)
batchArray[batchIndex].update(document.ref, {
fromUserFullname: fromUserFullname,
forUserFullname: forUserFullname,
forUserProfileImageURL: forUserProfileImageURL
})
operationCounter++
if(operationCounter == 499){
batchArray.push(db.batch())
batchIndex++
operationCounter = 0
}
});
batchArray.forEach(async batch => await batch.comit)
return
}
})
})
async function getFromInfo(data: Document){
const userQuery = await db.collection('users').doc(data.uid).get()
return userQuery.fullname;
}
async function getForInfo(data: Document){
const userQuery = await db.collection('users').doc(data.uid).get()
return [userQuery.fullname, userQuery.profileImageURL];
}
Context:
profileImageURL
is a field of a user document that stores the user's profile
fullname
is a field of a user document that stores the user's full name
Questions:
- Is my approach correct/feasible at all? Or is there a better approach?
- What is the syntax to pass the document data into the async functions so that the data will be grabbed from the corresponding users
- Is my approach with await and async functions going to properly handle the thread issue of having to query for the user data to populate
fromUserFullname
and the other objects I am writing?