Frank Mendez
Frank Mendez

Reputation: 572

How to update nested document within nested document in firestore?

Here is my function

exports.updateUserSettings = functions.https.onRequest((request, response) => {
  cors(request, response, () => {
    setResponseHeaders(response);
    console.log('input', request.body);
    const name = request.body.name;
    const settings = request.body.settings;

     return db
      .collection(COLLECTION_USERS)
      .doc(name)
      .update(settings)
      .then(() => {
        return response.status(200).json({
          success: true,
          data: null
        });
      })
      .catch(error => {
        return response.status(200).json({
          success: false,
          error: error,
          data: null
        });
      });
  });
});

And here is my firestore documententer image description here

I want to update my settings object. And here is my request body

 { name: 'frank6',
   settings: '{"autoPass":true,
   "autoRoll":true,
   "colors": {
     "check":"#000000", 
     "dark":"#b58863", 
     "light":"#f0d9b5", 
     "mate":"#ff4500", 
     "selected":"#90ee90", 
     "source":"#90ee90", 
     "target":"#228b22"
    }, 
   "language":"en",
   "showCheckMoves":true,
   "showFileRank":true,
   "showLastOpponentMove":true,
   "showMateMoves":true,
   "showMoves":true,
   "sounds":true,
   "view":"2D"
   }' 
 }

It has an error Error: Value for argument "data" is not a valid Firestore document. Input is not a plain JavaScript object. I know how to update nested documents based on https://firebase.google.com/docs/firestore/manage-data/add-data#update_fields_in_nested_objects but I'm not sure why this error is occuring maybe I need to format my request body but I'm now sure how.

Also I have my request from my flutter dart web app

Future<void> updateUserSettings(ChexiUser user) async {
  await http.post(CLOUD_FUNCTIONS_BASE_URL + '/updateUserSettings', body: {
    'name': user.name,
    'settings': convert.jsonEncode(user.toSettingsFirebaseDocument())
  });
}

Here is my toSettingsFirebaseDocument function

Map<String, dynamic> toSettingsFirebaseDocument() {
  return {
    'autoPass': settingsAutoPass,
    'autoRoll': settingsAutoRoll,
    'colors': {
      'check': settingsColorsCheck,
      'dark': settingsColorsDark,
      'light': settingsColorsLight,
      'mate': settingsColorsMate,
      'selected': settingsColorsSelected,
      'source': settingsColorsSource,
      'target': settingsColorsTarget
    },
    'language': settingsLanguage,
    'showCheckMoves': settingsShowCheckMoves,
    'showFileRank': settingsShowFileRank,
    'showLastOpponentMove': settingsShowLastOpponentMove,
    'showMateMoves': settingsShowMateMoves,
    'showMoves': settingsShowMoves,
    'sounds': settingsSounds,
    'view': settingsView
  };
  }
 }

Upvotes: 1

Views: 483

Answers (1)

Frank Mendez
Frank Mendez

Reputation: 572

Okay so it turns out it was just a simple mistake. I just need to wrap my request.body with JSON.parse()

const settings = JSON.parse(request.body.settings);

And it's working properly. I'm not going to delete this question maybe it will be useful to others encountering similar issue.

Upvotes: 3

Related Questions