2017-10-15 88 views
6

Şu anda Firestore'u deniyorum ve çok basit bir şeye takılıyorum: "bir dizinin güncellenmesi (bir alt belgenin adı)".Firestore ile "nesne dizisi" nasıl güncellenir?

DB yapmam süper basit. Örneğin:

proprietary: "John Doe" 
sharedWith: 
    [ 
    {who: "[email protected]", when:timestamp} 
    {who: "[email protected]", when:timestamp} 
    ] 

Ben nesnelerin shareWith diziye yeni kayıtlar itmek (başarı olmadan) çalışıyorum.

denedim:

// With SET 
firebase.firestore() 
.collection('proprietary') 
.doc(docID) 
.set(
    { sharedWith: [{ who: "[email protected]", when: new Date() }] }, 
    { merge: true } 
) 

// With UPDATE 
firebase.firestore() 
.collection('proprietary') 
.doc(docID) 
.update({ sharedWith: [{ who: "[email protected]", when: new Date() }] }) 

Yok çalışır. Bu sorgular dizimin üzerine yazılıyor.

Cevap basit olabilir, ama bunu kendin bul ...

Teşekkür

cevap

8

tek Dizi öğesi güncelleştirmek (veya tek bir eleman ekleme/kaldırma) için hiçbir yol yoktur Bulut Firestore. Burada

Bu kod:

firebase.firestore() 
.collection('proprietary') 
.doc(docID) 
.set(
    { sharedWith: [{ who: "[email protected]", when: new Date() }] }, 
    { merge: true } 
) 

Bu proprietary/docID şekilde sharedWith = [{ who: "[email protected]", when: new Date() } de belgeyi ayarlamak için ancak varolan herhangi bir belge özelliklerini etkilemez diyor. update() çağrısı, update() çağrısı başarısız olsa bile, set() numaralı çağrıyı sağladığınız bildirime çok benzer.

İstediğiniz şeyi elde etmek için iki seçeneğiniz var.

Seçenek 1 - Set ilk DB'den değerlerinin izlenmesi gerekecektir dizinin tüm içeriğini, ile tüm dizi

Çağrı set(). Eşzamanlı güncellemelerden endişe ediyorsanız, tüm bunları bir işlemde yapabilirsiniz.

Seçenek 2 - kullanın subcollection

Sen sharedWith ana belgenin bir subcollection yapabiliriz. Sonra tek bir öğe ekleyerek şu şekilde görünecektir: Elbette

firebase.firestore() 
    .collection('proprietary') 
    .doc(docID) 
    .collection('sharedWith') 
    .add({ who: "[email protected]", when: new Date() }) 

bu yeni sınırlamalar söz konusudur. Kiminle paylaşıldıklarına göre belgelerini sorgulayamazsınız ve dokümanını ve tüm sharedWith verilerini tek bir işlemle gerçekleştirebilirsiniz.

+0

Bu çok sinir bozucu ... ama bana verdiğin için teşekkürler Ben deli gitmiyorum biliyorum. – ItJustWerks

+8

Bu büyük dezavantaj, Google en kısa zamanda düzeltmek zorunda. –

2

// say you have have the following object and 
    // database structure as you mentioned in your post 
    data = { who: "[email protected]", when: new Date() }; 

    ...othercode 


    addSharedWith(data) { 

    const postDocRef = this.afs.collection('posts').doc('docID'); 

    postDocRef.subscribe(post => { 

     // Grab the existing sharedWith Array 
     // If post.sharedWith doesn`t exsit initiated with empty array 
     const foo = { 'sharedWith' : post.sharedWith || []}; 

     // Grab the existing sharedWith Array 
     foo['sharedWith'].push(data); 

     // pass updated to fireStore 
     postsDocRef.update(foo); 
     // using .set() will overwrite everything 
     // .update will only update existing values, 
     // so we initiated sharedWith with empty array 
    }); 
} 
: aynı zamanda bir 3 seçenek

const booking = { some: "data" }; 
    const userRef = this.db.collection("users").doc(userId); 

    this.db.runTransaction(transaction => { 
     // This code may get re-run multiple times if there are conflicts. 
     return transaction.get(userRef).then(doc => { 
      if (!doc.data().bookings) { 
       transaction.set({ 
        bookings: [booking] 
       }); 
      } else { 
       const bookings = doc.data().bookings; 
       bookings.push(booking); 
       transaction.update(userRef, { bookings: bookings }); 
      } 
     }); 
    }).then(function() { 
     console.log("Transaction successfully committed!"); 
    }).catch(function (error) { 
     console.log("Transaction failed: ", error); 
    }); 
0

Sam Stern's answer üzerine inşa etmek var Bu, benim için işleri daha kolay hale getiren ve Google’ın bir Harita olarak adlandırdığı şeyi kullanıyor. Bu aslında bir sözlük.

Ben bir sözlük Tarif ettiğiniz kullanımlar için çok daha iyi olduğunu düşünüyorum. Genelde çok fazla güncellenmeyen şeyler için diziler kullanırım, bu yüzden az ya da çok statiktirler. Fakat çok fazla yazılan şeyler için, özellikle veritabanında başka bir şeye bağlı alanlar için güncellenmesi gereken değerler için, sözlüklerin bakımı ve çalışması çok daha kolay olur.

Yani belirli bir durum için, DB yapısı şu şekilde görünecektir:

proprietary: "John Doe" 
sharedWith:{ 
    whoEmail1: {when: timestamp}, 
    whoEmail2: {when: timestamp} 
} 

Bu aşağıdakileri yapmanızı sağlayacaktır:

var whoEmail = '[email protected]'; 

var sharedObject = {}; 
sharedObject['sharedWith.' + whoEmail + '.when'] = new Date(); 
sharedObject['merge'] = true; 

firebase.firestore() 
.collection('proprietary') 
.doc(docID) 
.update(sharedObject); 

bir değişken olarak nesneyi tanımlayan nedeni 'sharedWith.' + whoEmail + '.when''un doğrudan set yönteminde kullanılması, en azından bir Node.js bulut işlevinde kullanıldığında bir hatayla sonuçlanacaktır.