ちょっと嵌ったのでメモ。
概要
FireStoreで、コレクションhogeにサブコレクションとしてfugaを追加し、
(hoge/hogeId/fuga/fugaId
という形)
hoge/hogeId/fuga/fugaId
のにだけドキュメントを追加して、
hoge/hogeId
には何もSetしなかった場合、
FireStoreのコンソール上ではhoge/hogeId
に何かしら存在するように見えますが
fireStoreのSDKからはデータを確認/取得はできません。
fireStore().collections('hoge').doc('hogeId').get().then((doc) => {
console.log(doc.exists);//false
});
実データがないのでデータ自体に困ることはありませんが、
サブコレクションを持っているドキュメントIDの一覧を取りたい場合や、上位のドキュメントIDを問わずサブコレクションのデータを取りたい場合に困ります。
理由
FireStoreはコンソールから見ると階層データ構造に見えますが、内部的にはKVSに近いので
hoge/hogeId/fuga/fugaId
は単なるパスに過ぎず、これにデータを入れたからと言って親としてhoge/hogeId/
が生成されるわけではありません。
でも管理コンソールでは空ドキュメントも含めて描画してるけど
実はAdminSDK側には、空でもサブコレクションがあればdocIDを取ってくるlistDocumentsというAPIが実装されています。
自分でDBツールを自作する時はこれを使えばいいのでは?
通常のSDKでも何とか空ドキュメントの一覧を取ったりサブコレクションの一覧が欲しい場合は?
- 通常のSDKにはlistDocumentsがないので、空ドキュメントのIDを取るのは無理です。
- 一覧が欲しい場合には別ドキュメントやコレクションで管理しましょう。
- 下位のサブコレクションに対しクエリを投げたい場合はコレクショングループクエリを使う手もあります。
- そもそも素直に欲しいデータが取れない時点でDB設計をミスっているとも言えます。(自戒) NoSQLの時にはクエリドリブンにデータベース設計をしましょう。
- 厳密な即時反映が必要でなければCloudFunctionsを使って取りやすい形に非正規化もありです。