以下是我用来实现从 Firebase 实时数据库检索数据的分页代码。基本上,我正在尝试根据页码获取前 n 个内容,然后从第一个查询中检索到的数据中获取最后 n 个内容。
function getUserSnapshotOrVerifyUserId(username, idToken, cb) {
if (username == null || username.length == 0 || idToken == null || idToken.length == 0)
return cb({
status: "error",
errorMessage: "Missing params."
}, null);
admin.auth().verifyIdToken(idToken).then(decodedToken => {
let uid = decodedToken.uid;
admin.database().ref().child("users").orderByChild("username").equalTo(username).once('value', snapshot => {
if (!snapshot.exists())
return cb({
status: "error",
message: "invalid-profile"
});
snapshot.forEach(child => {
const id = child.val().id;
if (id !== uid)
return cb({
status: "error",
message: "Invalid ID"
});
admin.database().ref("users/" + id).once("value", snapshot => {
if (!snapshot.exists())
return cb({
status: "error",
errorMessage: "user not found."
});
return cb(null, id, snapshot);
});
});
});
}).catch(err => cb({
status: "error",
message: err
}));
}
exports.getUserContentTestPagination = functions.https.onRequest((req, res) => {
corsHandler(req, res, async () => {
try {
const username = req.body.username || req.query.username;
const idToken = req.body.idToken;
const limit = 2;
const page = req.body.page || 1;
const limitToFirst = page * limit;
const limitToLast = limit;
getUserSnapshotOrVerifyUserId(username, idToken, async (err, id) => {
if(err) return res.json(err);
const uploadsRef = admin.database().ref('uploads').orderByChild('createdBy').equalTo(id)
const firstnquery = uploadsRef.limitToFirst(limitToFirst);
const lastnquery = firstnquery.limitToLast(limitToLast);
lastnquery.once("value", snapshot => {
res.json({
snapshot
})
})
})
} catch (err) {
res.json({
status: "error",
message: err
})
}
});
});
我调用了一个函数timeout,但是当我使用 firstnquery
获取前 n 个数据时,它会如预期地返回前 n 个数据。所以问题出在 lastnquery
上。希望得到任何帮助。
更新 1:
exports.getUserContentTestPagination = functions.https.onRequest((req, res) => {
corsHandler(req, res, async () => {
try {
const username = req.body.username || req.query.username;
const idToken = req.body.idToken;
const limit = 2;
const page = req.body.page || 1;
let lastKnownKeyValue = null;
getUserSnapshotOrVerifyUserId(username, idToken, async (err, id) => {
if(err) return res.json(err);
const uploadsRef = admin.database().ref('uploads');
const pageQuery = uploadsRef.orderByChild('createdBy').equalTo(id).limitToFirst(limit);
pageQuery.once('value', snapshot => {
snapshot.forEach(childSnapshot => {
lastKnownKeyValue = childSnapshot.key;
});
if(page === 1){
res.json({
childSnapshot
})
} else {
const nextQuery = uploadsRef.orderByChild('createdBy').equalTo(id).startAt(lastKnownKeyValue).limitToFirst(limit);
nextQuery.once("value", nextSnapshot => {
nextSnapshot.forEach(nextChildSnapshot => {
res.json({
nextChildSnapshot
})
})
})
}
});
})
} catch (err) {
res.json({
status: "error",
message: err
})
}
});
});
startAt()
和equalTo()
,这就是为什么你在我的答案中看到我传递了两个参数给.startAt(idOfLastItemOfPreviousPage, keyOfLastItemOfPreviousPage)
。第一个参数是要开始的createdBy
的值,第二个参数是要开始的键,以防有多个节点具有相同的createdBy
值。 - Frank van PuffelencreatedBy
的id进行排序,它怎么知道我只需要那个特定用户的上传文件?将createdBy
的值传递给startAt()
会如何让它知道我需要该特定用户的上传文件? - Cedric Hadjian