Спасибо Фрэнку из Firebase за помощь мне с этим кодом. У меня была только одна проблема с отправкой идентификатора документа в коллекцию друзей. Я не уверен, как лучше всего поместить const friendId и const accepted в массив friendsList в приведенном ниже коде.

const db = admin.firestore();
const friendRef = 
db.collection('users').doc(id).collection('friends');

friendRef.get().then((onSnapshot) => {
  var promises = [];

  onSnapshot.forEach((friend) => {
    const personId = String(friend.data().person_id);
    const friendId = String(friend.id);
    const accepted = friend.data().accepted;

    promises.push(db.collection('users').doc(personId).get());
  });

  Promise.all(promises).then((snapshots) => {
    friendsList = [];
    snapshots.forEach((result) => {
      friendsList.push({
        friendId: friendId,
        accepted: accepted,
        firstName: result.data().name.first,
        lastName: result.data().name.last,
      });
    });
    res.send(friendsList);
  });
}).catch((e) => {
  res.send({
    'error': e
  });
})

Я пробовал несколько вещей, но ничего не вышло. Любая помощь будет оценена.

-1
user9105669 31 Дек 2017 в 01:43

2 ответа

Лучший ответ

Проблема в том, что вы вставляете в массив promises то, что вы получаете от вызовов db.collection('users').doc(personId).get() для каждого значения friend. И вы никогда не сохраняете значения personId, friendId, accepted для каждого друга, кроме как локальных переменных.

Вы должны соблюдать их в каждом массиве обещаний. Для этого вы можете вернуть пользовательское обещание вот так.

promises.push(new Promise((resolve, reject) => {
    db.collection('users').doc(personId).get()
    .then(docResult => {
        resolve({         
            friendId: friendId,
            accepted: accepted,
            doc: docResult
        });
    })
    .catch(reason => {
        reject(reason);
    });
});

А затем при итерации массива снимков:

snapshots.forEach((result) => {
    friendsList.push({
        friendId: result.friendId,
        accepted: result.accepted,
        firstName: result.doc.data().name.first,
        lastName: result.doc.data().name.last,
    });
});
3
Turkhan Badalov 30 Дек 2017 в 23:08

Как я только что прокомментировал в своем ответе на ваш исходный вопрос, в моем коде была опечатка, связанная с запутанными именами переменных.

const db = admin.firestore();
const friendRef = db.collection('users').doc(id).collection('friends');

friendRef.get().then((friendsSnapshot) => {
  var promises = [];

  friendsSnapshot.forEach((friend) => {
    const friendId = String(friend.data().person_id);    
    promises.push(db.collection('users').doc(friendId).get());
  });

  Promise.all(promises).then((friendDocs) => {
    friendsList = [];
    friendDocs.forEach((friendDoc) => {
      friendsList.push({
        personId: friendDoc.id,
        firstName: friendDoc.data().name.first,
        lastName: friendDoc.data().name.last,
      });
    });
    res.send(friendsList);
  });
}).catch((e) => {
  res.send({
    'error': e
  });
})

Поскольку вы ищите данные друга с помощью doc(friendId), friendDoc.id в обратном вызове then() будет идентификатором каждого друга.

В подобных случаях я настоятельно рекомендую держать справочную документацию Cloud Firestore под рукой. Например, в этом случае я нашел DocumentSnapshot.id делать то что надо.

0
Frank van Puffelen 31 Дек 2017 в 00:43