Для чого підходить тип даних 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.