Javascript + Firebase Realtime DatabaseでSQLのWHERE IN 的なことをしたい
Javascript + Firebase Realtime DatabaseでSQLのWHERE IN 的なことをしたい:
※タイトルにWHERE IN 的なことをしたいと書いていますが実際にはWHERE INとはほど遠く複数クエリをFirebaseに投げています
※そもそもFirebase Realtime Database自体が初心者なため、データ構造から自信がありません。 また、Promiseも理解しきれておりません。 もっと良い方法がありましたらご教示頂けると幸いです。
React+FirebaseでSPAを開発
Reactで開発しており、全てのデータを取得してからstateを更新したかった。 =>
これでやりたかったことは実現できました。
※タイトルにWHERE IN 的なことをしたいと書いていますが実際にはWHERE INとはほど遠く複数クエリをFirebaseに投げています
※そもそもFirebase Realtime Database自体が初心者なため、データ構造から自信がありません。 また、Promiseも理解しきれておりません。 もっと良い方法がありましたらご教示頂けると幸いです。
前提
React+FirebaseでSPAを開発
困ったこと
- あるユーザに紐付くデータ(モデル)が複数個ある
- 紐付けは以下のようにモデルのIDで持っている
"users": { "ID-USER-abcde": { "username": "tanaka", "data": { "ID-DATA-ABCDE": true, "ID-DATA-FGHIJ": true } }, ..snip.. }, "data": { "ID-DATA-ABCDE": { "num": 3 }, "ID-DATA-FGHIJ": { "num": 5 }, "ID-DATA-KLMNO": { "num": 8 }, ..snip.. }
- やりたいことはSQLでいう
SELECT * WHERE IN ("ID-DATA-ABCDE", "ID-DATA-FGHIJ");
- しかしFirebase Realtime Databaseにそのようにクエリする方法はない
方針
- 改めてFirebaseに用意されている関数を確認してみる。
orderByChild()、orderByKey()、orderByValue()
/limitToFirst()、limitToLast()、startAt()、endAt()、equalTo()
=> やりたいことはできなさそう - dataを全部持ってきてクライアントでフィルタする => 流石にネットワーク効率が非効率的な気がする
- userに対するdataはそこまで多くなる予定はないので、 一つ一つ取得する
やったこと
Reactで開発しており、全てのデータを取得してからstateを更新したかった。 => Promise.all
を使ったfirebase .db .ref("User's data") .once('value') .then(snapshot => { const dataObject = snapshot.val() // ["ID-DATA-ABCDE", "ID-DATA-FGHIJ"] にする const dataIds = Object.keys(dataObject) const promises = dataIds.map(v => firebase .db .ref("data") .once('value') ) // 全てのデータ取得が完了してからstateを更新する Promise.all(promises).then(v => { // [{"num": 3}, {"num": 5}] const data = v.map(snapshot => snapshot.val()) this.setState({ data loading: false }) }) })
const promises
もPromise.all
も.then
の外にだせる気もするんだけどjavascript力が弱い...
コメント
コメントを投稿