Skip to content

Instantly share code, notes, and snippets.

@Gaubee
Last active April 9, 2017 08:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gaubee/47bdd1f890f812d77ccdf41ced7ce92b to your computer and use it in GitHub Desktop.
Save Gaubee/47bdd1f890f812d77ccdf41ced7ce92b to your computer and use it in GitHub Desktop.
Firebase pagination
const admin = require("./firebase-admin");
admin.initializeApp({
credential: **yourCredential**
databaseURL: **yourDatabaseURL**
});
const db = admin.database();
const dbPromise = (db_ref, options = {}) => {
const {
can_null,
null_errormsg = "Can not find the specified data"
} = options;
return new Promise((resolve, reject) => {
db_ref.once("value", snapshot => {
const val = snapshot.val();
if (val || can_null) {
resolve(val)
} else {
reject(null_errormsg)
}
}, reject)
})
}
const usersRef = db.ref("users");
function formatMap(map) {
const res = [];
for (let k in map) {
const item = map[k];
const res_item = {
nickname: item.nickname,
create_time: item.create_time
}
res.push(res_item);
}
res.sort((a, b) => b.create_time - a.create_time)
return res;
}
async function run(page, num) {
const _page = (parseInt(page) || 1) - 1;
const _num = parseInt(num) || 10;
const _from = _page * _num;
const _to = _from + _num;
let list;
if (_from) {
const pre_map = await dbPromise(usersRef.orderByChild("create_time").limitToLast(_from));
const pre_map_noop = function() {};
pre_map_noop.prototype = pre_map;
const pre_map_keys = Object.keys(pre_map);
let min_create_time = Infinity;
const min_item_key_set = new Set();
for (var i = 0; i < pre_map_keys.length; i += 1) {
var pre_map_key = pre_map_keys[i]
var pre_map_item_create_time = pre_map[pre_map_key].create_time;
if (pre_map_item_create_time < min_create_time) {
min_create_time = pre_map_item_create_time;
min_item_key_set.clear()
min_item_key_set.add(pre_map_key)
} else if (pre_map_item_create_time === min_create_time) {
min_item_key_set.add(pre_map_key)
}
}
const min_item_key_set_size = min_item_key_set.size;
const map = await dbPromise(usersRef.orderByChild("create_time")
.endAt(min_create_time, "create_time")
.limitToLast(_num + min_item_key_set_size)
);
const map_noop = function() {};
map_noop.prototype = map; // 让nodejs引擎优化成fast-object
const map_keys = Object.keys(map); // Object.keys比for in快
const res_list = [];
for (var i = 0; i < map_keys.length; i += 1) {
var map_key = map_keys[i];
if (!min_item_key_set.has(map_key)) {
res_list[res_list.length] = map[map_key];
}
}
list = res_list;
} else {
const map = await dbPromise(usersRef.orderByChild("create_time").limitToLast(_to));
const noop = function() {};
noop.prototype = map;
const map_keys = Object.keys(map);
const res_list = [];
for (var i = 0, last_i = map_keys.length - 1; i <= last_i; i += 1) {
res_list[last_i - i] = map[map_keys[i]];
}
list = res_list;
}
list.sort((a, b) => b.create_time - a.create_time);
return {
page: _page + 1,
num: _num,
list
}
};
run(2, 4).then(res => {
console.log(JSON.stringify(res.list.map(item => {
return {
nickname: item.nickname,
create_time: item.create_time
}
}), null, 2));
setTimeout(() => {
console.log("EXIT SERVER")
process.exit(0);
}, 100)
}).catch(e => {
console.log("ERRRR", e)
process.exit(0);
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment