I am running a for-loop function to create/add new documents to existing collection within Firestore from iOS app. Although I am only creating about 48 documents, which is much lower than stated write limit (500 documents per second) based on the documentation -
Is this something that is normal? or is it that my swift code were not "optimized"? '
With advice from @Joakim Danielson, I tried to ADD/CREATE smaller number of documents to the Firestore, but the latency or the creation rate stayed about the same where each document took about 0.2 seconds to be created.
I am getting quite worried for the user experience of the app although it is only once that such creation process take place for a new user, I foresee larger number of documents being created a new user. Please review my code below and let me konw if there is any other best practice I can utilize.
Below is a screenshot of the Xcode console for reference on the time the documents get created.
func createAndReadUserSpecificDayProgramDataToFirestore() {
print("codementor: createAndReadUserSpecificDayProgramDataToFirestore started")
let tabbar = tabBarController as! MainTabBarController
guard let userID = Auth.auth().currentUser?.uid else {
print("no current user logged in")
return
}
print("create user specific dayprogram profile using for loop and dayprogram list in tabbar")
if tabbar.dayProgramList.count == 0 {
print("tabbar day program list has no day program profile")
return
}
startActivityIndicator()
for dayprogram in tabbar.dayProgramList {
print("dayprogram forloop executed")
var ref: DocumentReference? = nil
print("codementor: document is adding")
ref = self.db.collection("Day").addDocument(data: [
"author_uid": dayprogram.author_uid ?? "",
"barbellWeight": dayprogram.barbellWeight ?? "",
"benchWeight": dayprogram.benchWeight ?? "",
"createDate": dayprogram.createDate ?? Date(),
"dayId": dayprogram.dayId ?? "",
"dayIntensity": dayprogram.dayIntensity ?? "",
"daySequence": dayprogram.daySequence ?? "",
"deadliftWeight": dayprogram.deadliftWeight ?? "",
"defaultRestTime": dayprogram.defaultRestTime ?? "",
"isPublicFlag": dayprogram.isPublicFlag ?? "",
"lastUpdatedBy": dayprogram.lastUpdatedBy ?? "",
"numberOfExercise": dayprogram.numberOfExercise ?? "",
"overheadWeight": dayprogram.overheadWeight ?? "",
"prcntComplete": dayprogram.prcntComplete ?? "",
"squatWeight": dayprogram.squatWeight ?? "",
"status": dayprogram.status ?? "",
"targetRestEndHR": dayprogram.targetRestEndHR ?? "",
"workoutDate": dayprogram.workoutDate ?? "",
"workoutId": dayprogram.workoutId ?? "",
"userID": userID
], completion: { err in
self.programCount = 1
if self.programCount == tabbar.dayProgramList.count {
print("dayprogram forloop function, which is to create user specific profile completed at \(CFAbsoluteTimeGetCurrent())")
self.createAndOrReadUserSpecificDayProgramData()
self.stopActivityIndicator()
print("forlopp dayprogram all calls finished")
}
if let err = err {
print("Error adding user specific dayprogram profile: \(err)")
} else {
print("timestamp successfully adding: \(CFAbsoluteTimeGetCurrent())")
print("User specific dayprogram profile added with ID: \(ref!.documentID)")
}
print("forlopp dayprogram \(ref!.documentID) finished")
})
print("forlopp dayprogram `dispatchGroup.leave()` was here, but this was the wrong place")
}
print("forlopp dayprogram more exucution if there was any")
}
CodePudding user response:
Using batches instead of uploading individual documents
func createAndReadUserSpecificDayProgramDataToFirestore() {
print("codementor: createAndReadUserSpecificDayProgramDataToFirestore started")
let tabbar = tabBarController as! MainTabBarController
guard let userID = Auth.auth().currentUser?.uid else {
print("no current user logged in")
return
}
print("create user specific dayprogram profile using for loop and dayprogram list in tabbar")
if tabbar.dayProgramList.count == 0 {
print("tabbar day program list has no day program profile")
return
}
startActivityIndicator()
let batch = db.batch()
for dayprogram in tabbar.dayProgramList {
print("dayprogram forloop executed")
var ref: DocumentReference = db.collection("myCollection").document()
batch.setData([
"author_uid": dayprogram.author_uid ?? "",
"barbellWeight": dayprogram.barbellWeight ?? "",
// your data
"workoutId": dayprogram.workoutId ?? "",
"userID": userID
], forDocument: ref)
self.programCount = 1
}
// this writes everything to the database all at once.
// if ANY of them fail, an error will be thrown
// and the entire operation fails
batch.commit { err in
if self.programCount == tabbar.dayProgramList.count {
print("dayprogram forloop function, which is to create user specific profile completed at \(CFAbsoluteTimeGetCurrent())")
self.createAndOrReadUserSpecificDayProgramData()
self.stopActivityIndicator()
print("forlopp dayprogram all calls finished")
}
}
print("forlopp dayprogram more exucution if there was any")
}