我正在尝试查询我的数据库,以便它根据子键检索有序列表。我这样做(见下文),但没有任何反应,这意味着它返回一个完全按照存储在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"
答案 0 :(得分:76)
当您调用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 :(得分:15)
我知道这个问题已经回答并且已经超过1年了,但由于评论部分仍有一些混淆,我想补充一些信息。
最初的问题是OP想要根据Firebase实时数据库中的子密钥检索有序列表,但* Hostname was NOT found in DNS cache
* Trying 204.9.224.11...
* Connected to familysearch.org (204.9.224.11) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSL connection using AES128-SHA
* Server certificate:
* subject: C=US; ST=Utah; L=Salt Lake City; O=Intellectual Reserve Inc.; OU=Intellectual+Reserve+Inc.; CN=*.familysearch.org
* start date: 2015-06-01 00:00:00 GMT
* expire date: 2017-06-05 12:00:00 GMT
* subjectAltName: familysearch.org matched
* issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=DigiCert SHA2 High Assurance Server CA
* SSL certificate verify ok.
> GET /platform/tree/persons/LVDH-ZZT/families.json HTTP/1.1
Host: familysearch.org
Accept: */*
Authorization: BearerUSYS79A3702777*****************************
< HTTP/1.1 401 Unauthorized
< Cache-Control: no-cache, no-store, no-transform, must-revalidate, max-age=0
< Content-Location: /tree/persons/LVDH-ZZT/families
< Content-Type: application/json
< Date: Thu, 08 Dec 2016 12:53:04 GMT
< Link: <https://ident.familysearch.org/cis-web/oauth2/v3/authorization>; rel="http://oauth.net/core/2.0/endpoint/authorize"
< Link: <https://ident.familysearch.org/cis-web/oauth2/v3/token>; rel="http://oauth.net/core/2.0/endpoint/token"
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Vary: Accept, Accept-Language, Accept-Encoding, Expect
< Vary: Accept-Encoding
< Warning: 400 FamilySearch "Unable to read tf person."
< Warning: 199 FamilySearch Best Practice Violation: Should specify versioned media type in Accept header, e.g. one of [ "application/x-gedcomx-v1+xml", "application/x-gedcomx-v1+json", "application/atom+xml", "application/x-gedcomx-atom+json", "application/x-fs-v1+xml", "application/x-fs-v1+json" ].
< X-PROCESSING-TIME: 5
< transfer-encoding: chunked
< Connection: Close
<
* Closing connection 0
{
"errors" : [ {
"code" : 401,
"message" : "Unable to read tf person.",
"stacktrace" : "GET http://tf.prod.us-east-1.prod.fslocal.org/tf/person/LVDH-ZZT?oneHops=cards returned a response status of 401 Unauthorized:\n{\n\"401\": \"Unauthorized\"\n}"
} ]
}
无法按预期工作。
但是没有按预期工作的不是.orderByChild('arg')
,而是.orderByChild('arg')
。因为.on("value", callback)
与.on("value", callback)
等其他eventType有点不同。
假设我们有一个firebase实时数据库,如下所示:
.on("child_added", callback)
-
如果我们使用{
myData: {
-KYNMmYHrzLcL-OVGiTU: {
NO: 1,
image: ...
},
-KYNMwNIz4ObdKJ7AGAL: {
NO: 2,
image: ...
},
-KYNNEDkLpuwqQHSEGhw: {
NO: 3,
image: ...
},
}
}
,则回调()将被调用一次,并返回一个包含3个对象的对象数组。
.on("value", callback)
-
如果我们使用ref.on("value", function(snapshot) {
console.log(snapshot.val());
// Please see Frank van Puffelen's answer
}
,则回调()将被调用3次,每次返回一个对象,并按顺序返回 。
.on("child_added", callback)
如果您只需要从firebase获取有序数据(例如初始化UI)。那么ref.once("child_added", function(snapshot) {
console.log(snapshot.val());
// The objects are returned in order, do whatever you like
}
非常适合您,它简单易用。
但是,如果出于某种原因需要使用ref.orderByChild('arg').once("child_added", callback)
,请参阅Frank van Puffelen的回答。
请阅读Firebase Document,了解有关ref.orderByChild('arg').on("value", callback)
,其参数及其返回值的详情。
另一个有用的文件:Work with Lists of Data on the Web
答案 2 :(得分:2)
使用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
答案 3 :(得分:0)
我在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;
}
}];