Last active
April 9, 2017 08:13
-
-
Save Gaubee/47bdd1f890f812d77ccdf41ced7ce92b to your computer and use it in GitHub Desktop.
Firebase pagination
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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