Apa yang cocok untuk tipe data 'Referensi' Firebase Firestore?

189

Saya hanya menjelajahi Firebase Firestore baru dan berisi tipe data yang disebut reference. Tidak jelas bagi saya apa yang dilakukannya.

  • Apakah itu seperti kunci asing?
  • Bisakah itu digunakan untuk menunjuk ke koleksi yang terletak di tempat lain?
  • Jika referencemerupakan referensi aktual, dapatkah saya menggunakannya untuk permintaan? Sebagai contoh, bisakah saya memiliki referensi yang menunjuk langsung ke pengguna, daripada menyimpan userId di bidang teks? Dan bisakah saya menggunakan referensi pengguna ini untuk menanyakan?
Jürgen Brandstetter
sumber
18
Saya pikir video ini dari tim firebase memecahnya untuk Anda: youtube.com/watch?v=Elg2zDVIcLo (tonton dari 4:36)
Adarsh

Jawaban:

91

Referensi sangat mirip dengan kunci asing.

SDK yang saat ini dirilis tidak dapat menyimpan referensi ke proyek lain. Dalam suatu proyek, referensi dapat menunjuk ke dokumen lain dalam koleksi lainnya.

Anda dapat menggunakan referensi dalam kueri seperti nilai lainnya: untuk memfilter, memesan, dan untuk paging (startAt / startAfter).

Tidak seperti kunci asing dalam database SQL, referensi tidak berguna untuk melakukan penggabungan dalam satu permintaan. Anda dapat menggunakannya untuk pencarian dependen (yang terlihat seperti bergabung), tetapi hati-hati karena setiap hop akan menghasilkan perjalanan pulang-pergi lain ke server.

Gil Gilbert
sumber
9
Tolong, bisakah Anda membagikan kemungkinan kasus penggunaan? Apakah mungkin untuk menanyakan bidang dalam referensi itu? Misalnya saya punya friendskoleksi yang mencantumkan semua teman saya ( friends/myId). Lalu, saya merujuk dokumen ini di friendsbidang dokumen lain ( group/groupId). Saya ingin menampilkan hanya teman-teman saya yang berada di kelompok itu, melakukan sesuatu seperti ini: where('friends.myId', '==', true).
Will
108
Btw, mungkin berguna untuk memperbarui dokumen untuk menyertakan contoh menambahkan jenis referensi.
Will
11
Saya tidak dapat menemukan info tentang ini? Ini akan mengubah seluruh struktur basis data saya, saya perlu tahu lebih banyak ...
Ruben
3
apakah Anda memiliki contoh (lebih disukai dengan cepat) tentang cara kueri menggunakan referensi? sekarang, saya bisa melakukannya dengan menyimpan uid mentah sebagai string, tapi itu sepertinya tidak benar.
Mickey Cheong
6
Saya perlu mengubah semua jenis referensi saya menjadi string karena kueri selalu gagal dengan jenis referensi. Saya benar-benar tidak dapat menemukan apa pun tentang cara melakukan kueri dengan jenis referensi :( jika ada yang tahu cara melakukan kueri menurut jenis referensi, beri tahu saya ...
Sam Trent
133

Menambahkan di bawah ini apa yang berhasil bagi saya menggunakan referensi di Firestore.

Seperti jawaban yang lain katakan, itu seperti kunci asing. Atribut referensi tidak mengembalikan data dari dokumen referensi. Sebagai contoh, saya punya daftar produk, dengan referensi userRef sebagai salah satu atribut pada produk. Mendapatkan daftar produk, memberi saya referensi pengguna yang menciptakan produk itu. Tetapi itu tidak memberi saya rincian pengguna dalam referensi itu. Saya telah menggunakan ujung belakang lain sebagai layanan dengan pointer sebelum yang memiliki bendera "populate: true" yang memberikan rincian pengguna kembali, bukan hanya id referensi pengguna, yang akan lebih baik untuk memiliki di sini (semoga perbaikan di masa depan ).

Di bawah ini adalah beberapa contoh kode yang saya gunakan untuk mengatur referensi serta mendapatkan koleksi daftar produk kemudian mendapatkan detail pengguna dari id referensi pengguna yang diberikan.

Tetapkan referensi pada koleksi:

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

Dapatkan koleksi (produk) dan semua referensi pada setiap dokumen (detail pengguna):

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) });

Semoga ini membantu

Ben Cochrane
sumber
3
Terima kasih telah berbagi! Saya pikir ada kesalahan ketik pada baris pertama dari Dapatkan bagian dan itu seharusnya db.collection('products').get(). Sudahkah Anda mencoba mendapatkan pengguna secara langsung? Saya kira lebih baik newItem.userRef.get()bekerja daripadadb.collection("users").doc(newItem.userRef.id).get()
Sergey Nefedyev
53
Pertama-tama terima kasih atas contohnya. Saya berharap mereka akan menambahkan "mengisi: benar" untuk masa depan. Kalau tidak menyimpan referensi agak tidak ada gunanya. Hal yang sama bisa dilakukan hanya dengan menyimpan uiddan referensi melalui itu.
Jürgen Brandstetter
4
Terima kasih untuk contohnya! Tapi apa gunanya menyimpan tipe referensi jika tidak ada jenis "mengisi" pilihan ketika kita meminta dokumen? Jika ada opsi mengisi yang diketahui siapa pun, beri tahu saya.
Harshil Shah
18
Jadi sebenarnya tidak seperti kunci asing. Bagi saya itu pada dasarnya tidak apa-apa - apa gunanya referencejika kita tidak dapat menggunakannya sebagai kunci asing yang benar harus bekerja?
jean d'arme
14
Jadi satu-satunya keuntungan dari referencelebih stringadalah, bahwa Anda dapat memanggil get()referensi secara langsung. Belum terlalu berguna. Semoga mereka menambahkan opsi untuk secara otomatis mengisi referensi dengan objek yang sesuai!
morgler
16

Bagi mereka yang mencari solusi Javascript untuk query dengan referensi - konsepnya adalah, Anda perlu menggunakan objek 'referensi dokumen' dalam pernyataan permintaan

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

(Kudos untuk jawabannya di sini: https://stackoverflow.com/a/53141199/1487867 )

Aswin Kumar
sumber