子キーに基づいて順序付けられたリストを取得するようにデータベースを照会しようとしています。私はそれを次のように行いますが(以下を参照)、何も起こりません。つまり、Firebaseデータベースに保存されているのとまったく同じ方法で順序付けられたオブジェクトを返します。何が起こっている?
self.getAllProfiles = function () {
var qProfile = $q.defer();
var ref = new Firebase(FBURL);
ref.child("users").orderByChild('last_update').on("value", function (snapshot) {
console.log(snapshot.val()) // HERE IS WHERE IT SHOULD BE ORDERED
qProfile.resolve(snapshot.val());
}, function (errorObject) {
qProfile.reject(errorObject);
});
return qProfile.promise;
};
追加するには、ユーザーノードは次のようになります。
users
/$username
/last_update
/id
/data
/profile_image
/display_name
スナップショットは次のとおりです。
Tester: Object
github: Object
last_update: 1447732462170
userId: "github:12345"
snapshot.val()
を呼び出すと、JSONオブジェクトが返されます。 JSONオブジェクト内のキーの順序は、Firebaseではなくブラウザーによって決定されます。
子を順番に取得するには:
_self.getAllProfiles = function () {
var qProfile = $q.defer();
var ref = new Firebase(FBURL);
ref.child("users").orderByChild('last_update').on("value", function (snapshot) {
snapshot.forEach(function(child) {
console.log(child.val()) // NOW THE CHILDREN PRINT IN ORDER
});
qProfile.resolve(snapshot.val());
}, function (errorObject) {
qProfile.reject(errorObject);
});
return qProfile.promise;
};
_
q.resolve()
呼び出しはそのままにしておくことができます。snapshot.forEach()
は非同期呼び出しではありません。
この質問に対する回答は1年以上前のものですが、コメントセクションにはまだ混乱があるため、情報を追加したいと思います。
元の問題は、OPがFirebaseリアルタイムデータベースの子キーに基づいて順序付けられたリストを取得したいが、.orderByChild('arg')
が期待どおりに機能しないことです。
しかし、期待どおりに機能しなかったのは.orderByChild('arg')
ではなく、.on("value", callback)
です。 .on("value", callback)
は、.on("child_added", callback)
のような他のeventTypeとは少し異なるためです。
以下のように、firebaseリアルタイムデータベースがあるとします。
_{
myData: {
-KYNMmYHrzLcL-OVGiTU: {
NO: 1,
image: ...
},
-KYNMwNIz4ObdKJ7AGAL: {
NO: 2,
image: ...
},
-KYNNEDkLpuwqQHSEGhw: {
NO: 3,
image: ...
},
}
}
_
-
.on("value", callback)
を使用すると、callback()が1回呼び出され、3つのオブジェクトのオブジェクト配列を返します。
_ref.on("value", function(snapshot) {
console.log(snapshot.val());
// Please see Frank van Puffelen's answer
}
_
-
.on("child_added", callback)
を使用すると、callback()が3回呼び出され、毎回Objectが返され、順番にが返されます。
_ref.once("child_added", function(snapshot) {
console.log(snapshot.val());
// The objects are returned in order, do whatever you like
}
_
Firebaseから順序付けられたデータのみを取得する必要がある場合(たとえば、UIを初期化する場合)、ref.orderByChild('arg').once("child_added", callback)
が適切です。これはシンプルで使いやすいです。
ただし、何らかの理由でref.orderByChild('arg').on("value", callback)
を使用する必要がある場合は、Frank van Puffelenの答えを参照してください。
on(eventType, callback, cancelCallbackOrContext, context)
、引数、戻り値の詳細については、 Firebase Document をお読みください。
別の便利なドキュメント: Web上のデータのリストを操作する
value
イベントリスナーを使用した注文の場合:
firebase.database().ref('/invoices').orderByChild('name').on('value', snapshot => {
snapshot.forEach(child => {
console.log(child.key, child.val());
});
}
順序を逆にする場合は、次を試してください。
function reverseSnapshotOrder (snapshot) {
let reversed = [];
snapshot.forEach(child => {
reversed.unshift(child);
});
return reversed;
}
reverseSnapshotOrder(snapshot).forEach(child => {
console.log(child.key, child.val());
});
参照してください: https://firebase.google.com/docs/database/web/lists-of-data#listen_for_value_events
IOSでも同じ問題に苦労しました。スナップショットをNSDictionaryオブジェクトに変換すると、順序なしリストに変換されます。必要な場合のObjective-cバージョン:
[[self.refChild queryOrderedByChild:@"date_created"]
observeEventType:FIRDataEventTypeValue
withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
for (FIRDataSnapshot *child in snapshot.children) {
NSDictionary *anObject = child.value;
NSString *aKey = child.key;
}
}];