Для чого підходить тип даних Firebase Firestore 'Reference'?


189

Я тільки досліджую новий Firebase Firestore, і він містить тип даних, який називається reference. Мені незрозуміло, що це робить.

  • Це як закордонний ключ?
  • Чи можна використовувати його для вказівки на колекцію, яка знаходиться десь деінде?
  • Якщо referenceце фактична довідка, чи можу я використовувати її для запитів? Наприклад, чи можу я мати посилання, яке вказує безпосередньо на користувача, а не зберігати userId у текстовому полі? І чи можу я використовувати цю посилання користувача для запитів?

18
Я думаю, що це відео від команди Firebase розбиває його для вас: youtube.com/watch?v=Elg2zDVIcLo (дивитись о 4:36)
Adarsh

Відповіді:


91

Посилання дуже схожі на іноземні ключі.

Наразі випущені пакети SDK не можуть зберігати посилання на інші проекти. У рамках проекту посилання можуть вказувати на будь-який інший документ у будь-якій іншій колекції.

Ви можете використовувати посилання у запитах, як і будь-яке інше значення: для фільтрації, замовлення та підкачки (startAt / startAfter).

На відміну від іноземних ключів у базі даних SQL, посилання не корисні для виконання об'єднань у одному запиті. Ви можете використовувати їх для залежних пошукових запитів (які, схоже, приєднуються), але будьте обережні, оскільки кожен перехід призведе до чергової поїздки на сервер.


9
Будь ласка, можете поділитися можливими випадками використання? Чи можливо запитувати поля в цій посиланні? Наприклад, у мене є friendsколекція з переліком усіх моїх друзів ( friends/myId). Потім я посилаюсь на цей документ у friendsполі іншого документа ( group/groupId). Я хотів би показати тільки моїх друзів , які знаходяться в цій групі, робити що - щось на зразок цього: where('friends.myId', '==', true).
Буде

108
До речі, може бути корисним оновити документи, щоб включити приклад додавання типу посилання.
Буде

11
Я не можу знайти інформацію про це? Це змінить всю мою структуру бази даних, мені потрібно знати більше ...
Рубен

3
у вас є приклад (бажано, швидко), як запитувати за допомогою посилання? зараз я можу це зробити, зберігаючи необроблений uid як рядок, але це не здається правильним.
Міккі Чонг

6
Мені потрібно змінити всі мої типи посилань на рядки, оскільки запит завжди буде невдалим із типом посилання. Я буквально не можу знайти нічого про те, як робити запит за типом посилання :( якщо хтось дізнається, як робити запит за референсними типами, дайте мені знати ...
Сем Трент

133

Додавши нижче те, що працювало для мене, використовуючи посилання в Firestore.

Як говорять інші відповіді, це як закордонний ключ. Атрибут посилання не повертає даних довідкового документа. Наприклад, у мене є список продуктів, в якому один із атрибутів продукту є посиланням на userRef. Отримавши перелік продуктів, дає мені інформацію про користувача, який створив цей продукт. Але це не дає мені реквізитів користувача в цій довідці. Я використовував інший бек-енд як сервіси з покажчиками до цього, має прапор "populate: true", який повертає інформацію про користувача, а не просто ідентифікаційний номер користувача, який би тут було чудово (сподіваємось, майбутнє вдосконалення) ).

Нижче наведено приклад коду, який я використовував для встановлення посилання, а також для отримання колекції списку продуктів, а потім отримайте реквізити користувачів із вказаного ідентифікатора користувача.

Встановлення посилання на колекцію:

let data = {
  name: 'productName',
  size: 'medium',
  userRef: db.doc('users/' + firebase.auth().currentUser.uid)
};
db.collection('products').add(data);

Отримайте колекцію (продукти) та всі посилання на кожен документ (реквізити користувача):

db.collection('products').get()
    .then(res => {
      vm.mainListItems = [];
      res.forEach(doc => {
        let newItem = doc.data();
        newItem.id = doc.id;
        if (newItem.userRef) {
          newItem.userRef.get()
          .then(res => { 
            newItem.userData = res.data() 
            vm.mainListItems.push(newItem);
          })
          .catch(err => console.error(err));
        } else {
          vm.mainListItems.push(newItem);  
        }

      });
    })
    .catch(err => { console.error(err) });

Сподіваюся, це допомагає


3
Дякую, що поділились! Я думаю, що в першому рядку Get part є помилка друку, і вона повинна бути db.collection('products').get(). Ви намагалися отримати користувача безпосередньо? Гадаю, newItem.userRef.get()замість цього має працюватиdb.collection("users").doc(newItem.userRef.id).get()
Сергій Нефєдєв,

53
Перш за все дякую за приклад. Я сподіваюся, що вони додадуть "поповнювати: правда" на майбутнє. Інакше зберігати посилання дещо безглуздо. Те ж саме можна було зробити, просто зберегти uidта посилатися через нього.
Юрген Брандштеттер

4
Дякую за приклад! Але який сенс зберігати тип посилання, якщо немає запиту "заповнити", коли ми запитуємо документ? Якщо є варіант заповнення, про який хтось знає, будь ласка, дайте мені знати.
Харшиль Шах

18
Тож насправді це не схоже на закордонний ключ. Для мене це взагалі нічого не робить - який сенс мати, referenceякщо ми не можемо використовувати його як справжній зовнішній ключ?
Жан д'арме

14
Тому єдиною перевагою referenceнад a stringє те, що ви можете зателефонувати get()за довідкою безпосередньо. Ще не дуже корисно. Сподіваємось, вони додають можливість автоматичного заповнення посилань відповідними об'єктами!
морґлер

16

Для тих, хто шукає рішення Javascript для запиту за посиланням - концепція полягає в тому, що вам потрібно використовувати об’єкт 'посилання на документ' в операторі запиту

teamDbRef = db.collection('teams').doc('CnbasS9cZQ2SfvGY2r3b'); /* CnbasS9cZQ2SfvGY2r3b being the collection ID */
//
//
db.collection("squad").where('team', '==', teamDbRef).get().then((querySnapshot) => {
  //
}).catch(function(error) {
  //
});

(Кудо відповідь тут: https://stackoverflow.com/a/53141199/1487867 )

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.