Final Update I changed from using a transaction based on the answer below from andresmijares, to using set().
This now allows me to write the data to the DB.
var gradeDocRef = db.collection("students").doc(studentId);
console.log(gradeDocRef);
var setWithMerge = gradeDocRef.set({
"UnitGrades": {
[unitNo]: {
"CG": CG,
"PG": PG,
"TG": TG
}
}
}, { merge: true });
Edit I altered code for the transaction based on the comment from andresmijares below.
transaction.set(gradeDocRef, {merge: true}, {
but then get this error?
Unknown option 'UnitGrades' passed to function Transaction.set(). Available options: merge, mergeFields
I have a cloud firestore database that contains a collection students. Each student collections contains a student document with a map and submap like below
UnitGrades:
{
IT1:
{
CG: "F"
PG: "F"
TG: "F"
id: "IT1"
name: "Fundamentals of IT"
type: "Exam"
}
I have 10 units within the map UnitGrades Each student has the same combination of units
I want to update the map based upon an HTML form in bootstrap (the form is working, plus is quite long so not put it in here)
i.e. change the student grades
I have used the firestore transaction update documentation and adapted slightly to take in data from a form in HTML.
let studentId = $(this).attr("data-student-id");
let unitNo = $(this).attr("data-unit");
let CG = $(this).attr("data-CG");
let PG = $(this).attr("data-PG");
let TG = $(this).attr("data-TG");
// Create a reference to the student doc.
var gradeDocRef = db.collection("students").doc(studentId);
console.log(gradeDocRef);
return db.runTransaction(function(transaction) {
// This code may get re-run multiple times if there are conflicts.
return transaction.get(gradeDocRef).then(function(gradeDoc) {
if (!gradeDoc.exists) {
throw "Document does not exist!";
}
// update the grades using a transaction
transaction.update(gradeDocRef, {
// in here is my error, I need to be able to select the map
// for the variable for UnitNo only and not wipe the other maps
"UnitGrades": {
[unitNo]: {
"CG": CG,
"PG": PG,
"TG": TG }
});
});
}).then(function() {
console.log("Transaction successfully committed!");
}).catch(function(error) {
console.log("Transaction failed: ", error);
console.log(studentId);
});
The code I have implemented updates the correct unit map but then wipes the rest of the UnitGrades. What I really want is to update the unit map identified in the variable
UnitNo and then leave the rest of the units untouched.
e.g. Currently if I update IT1 this correctly updates the grades within the map but then wipes units IT2, IT3, IT12 etc. from the UnitGrades map. I really want IT2, IT3, IT12 etc. to remain in place untouched and IT1 to be updated with the new values. e.g "F" changes to "P"