Сначала определите функцию map
для использования с firebase (с именем mapSnapshot
, потому что она предназначена специально для использования с firebase):
const mapSnapshot = f => snapshot => {
const r = [];
snapshot.forEach(x => { r.push(f(x)); });
return r;
}
Тогда вы можете просто работать с Promise
и mapSnapshot
:
function getStories() {
return db.collection('stories').
get().
then(mapSnapshot(doc => doc.data()));
}
Пример использования:
getStories().then(docs => ... do whatever with docs ...)
Если честно, код не будет меньше , если использовать его как разовое решение. Но здесь есть все, что нужно, это позволяет создавать многократно используемые абстракции . Так, например, вы могли бы использовать mapSnapshot
для создания snapshotToArray
функции, которую можно использовать повторно всякий раз, когда вам нужно преобразовать DataSnapshot из firebase в обычный Array
:
const snapshotToArray = mapSnapshot(x => x);
Обратите внимание: это не зависит от имени какой-либо коллекции . Вы можете использовать его с any DataSnapshot из any collection, чтобы преобразовать его в Array
!
Это еще не все. Вы также можете легко создать функцию из содержимого DataSnapshot в обычный Array
с содержимым в нем:
const readDocsData = mapSnapshot(x => x.data());
Опять же, это не выглядит большой проблемой - пока вы не поймете, вы также можете создать функцию fromFirebase
, которая позволяет запрашивать различные наборы данных:
const fromFirebase = (name, transform = x => x) => {
return db.collection(name).get().then(transform);
}
И что вы можете затем использовать следующим образом:
fromFirebase('stories', readDocsData).then(docs => {
// do what you want to do with docs
});
Таким образом, конечный результат будет меньше шагов, которые вы, как программист, сразу заметите. Но он произвел (хотя и многократно используемый) несколько промежуточных шагов, каждый из которых скрывал немного абстракции.