web-dev-qa-db-ja.com

Firebase-データを抽出するために複数のorderByChildを書き込むにはどうすればよいですか?

2つのフィールドが渡したものと等しいデータを取得しようとしています。

これが私のコードの例です:

this.refApp
  .orderByChild('userUid')
  .startAt(uid).endAt(uid)
  .orderByChild('jobId')
  .startAt(jobId).endAt(jobId)
  .on('value', (snap) => {
     //This currently doesn't get returned.
  });   

上記の例では、コンパイラエラーは発生せず、コードは問題ないようです。ただし、uidとjobidが等しいオブジェクトを返すようにデータをハードコーディングしました。

これを1つのorderByChildで機能させることができますが、上記のように2つ実行しても何も実行されないようです。

12
AngularM

使用できる注文方法は1つだけです。

さらにクエリを実行するには、データ構造を再考する必要があります。現在の構造はおそらく次のようになります。

{
  "key": {
     "id_1": {
        "userUid": "user_1",
        "jobId": "job_1"
     },
     "id_2": {
        "userUid": "user_1",
        "jobId": "job_2"
     },
     "id_3": {
        "userUid": "user_2",
        "jobId": "job_3"
     }
  }
}

この構造では、1つの子キーからのインデックス作成に制限されます。

次に、この構造を考えます。

{
   "key": {
      "user_1": {
         "id_1": {
            "jobId": "job_1",
            "userUid": "user_1"
         },
         "id_2": {
            "jobId": "job_2",
            "userUid": "user_1"
         }
      }
      "user_2": {
         "id_3": {
            "jobId": "job_3",
            "userUid": "user_2"
         }
      }
   }
}

この構造は、uidに明示的にインデックスを作成します。したがって、ユーザーごとにすべてのジョブを取得したい場合は、次のクエリを記述できます。

var ref = new Firebase('<my-firebase-app>');
var uid = 'user_1';
var userRef = ref.child('key').child(uid);
var query = userRef.orderByChild('jobId');
query.on('value', (snap) => console.log(snap.val());
7
David East

Firebaseで一種の複数のorderByChildを実行する別の方法は、orderKeyを作成することです。

あなたがこれをあなたの基地に持っていると想像してください:

_{
    userId: {
        firstName: 'Snow',
        lastName: 'Jon',
        birthYear: 283
    }
}
_

そして、あなたはクエリしたい:userRef.orderByChild('firstName').equalTo('Jon').orderByChild('lastName').equalTo('Snow')

次のように、ユーザーにキーを作成する必要があります。

_{
    userId: {
        firstName: 'Snow',
        lastName: 'Jon',
        birthYear: 283,
        orderName: 'JonSnow'
    }
}
_

したがって、次のようにクエリできます:userRef.orderByChild('orderName').equalTo('JonSnow')

これは、startAtおよびendAtでも機能します。これは、ある範囲の年に生まれたすべての雪を照会する場合に使用します。最初にキーを作成します。

_{
    userId: {
        firstName: 'Snow',
        lastName: 'Jon',
        birthYear: 283,
        orderNameYear: 'Snow283'
    }
}
_

だからあなたはクエリすることができます:userRef.orderByChild('orderNameYear').startAt('Snow280').endAt('Snow285')

これは、280から285の間に生まれたすべてのSnowを返します。

6
GuySake

サポートされていません。

エンティティで実行する必要があるクエリの種類に応じて、@ david-eastのようなユーザーごとにジョブを保存するか、2つのプロパティを組み合わせたプロパティを追加する必要があります。

{
 jobId: 'J123',
 userId: 'provider:123',
 jobIdUserIdIndex: 'J123/provider:12345',
 [...]
}

しかし、通常、必要なすべてのクエリを許可する方法はありません。クライアント側でオブジェクトをフィルタリングするか、データを複製してデータの異なるビューを作成する必要があります。 /jobs/$jobId/users/$userId/jobs/$jobId、場合によっては/pendingJobs/$jobIdにジョブデータが保存されます。

エンティティの順序付けにのみorderBy *メソッドを使用し、データを複製してそれらのサブセットを選択する方が簡単だと思います。

Firebaseが複数のプロパティを組み合わせたインデックスをサポートしてくれることを願っていますが、今のところ、それらを自分で作成する必要があります。ただし、ビューが異なると、ビューに異なるセキュリティルールを適用できます。 /users/$userId/jobs/にアクセスできるのは1人のユーザーのみで、/jobs/$jobIdにアクセスできるのは管理者だけです。

0
Dinoboff