クライアントが set() 全置換するドキュメントにサーバ書き込みフィールドを混ぜない
Firebase
設計判断
データモデリング
Firestore などのドキュメント DB で、クライアントが型付きモデルのシリアライズ結果を set()(merge なし=全置換)で保存するドキュメントに、サーバ側(Cloud Functions / バッチ処理)が管理フィールド(最終送信日時、処理済みフラグ等)を書き込むと、クライアントが次に設定を保存した瞬間にサーバのフィールドが静かに消える。モデルのシリアライザは自分の知らないフィールドを出力しないため、置換時に脱落する。
対処の選択肢と判断基準:
- 別ドキュメントに分離(推奨):
settings/default(クライアント所有)とsettings/meta(サーバ所有)のように所有者単位でドキュメントを分ける。互いの書き込みが干渉せず、セキュリティルールも所有者ごとに素直に書ける。 - クライアントを
set(merge: true)やupdate()に変える: 可能だが「フィールド削除」をしたい場面で FieldValue.delete の管理が必要になり、モデル⇔ドキュメントの対応が崩れやすい。 - モデルにサーバ用フィールドを追加: クライアントに不要な知識が漏れ、クライアントが古い値で上書きする競合リスクが残る。
症状からの気づき方: サーバ処理が「初回だけ動く」「ユーザーが設定を触ると再発する」場合、この上書き消失を疑う。検証はクライアントで設定保存→該当ドキュメントをコンソールで見てサーバ製フィールドが残っているか確認する。