javascript - फायरस्टार के साथ "वस्तुओं की एक सरणी" कैसे अपडेट करें?




arrays object (6)

मैं वर्तमान में फायरस्टार की कोशिश कर रहा हूं, और मैं बहुत ही सरल तरीके से फंस गया हूं: "एक सरणी को अपडेट करना (उर्फ एक उपनिर्देशन)"।

मेरी DB संरचना सुपर सरल है। उदाहरण के लिए:

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

मैं कोशिश कर रहा हूं (सफलता के बिना) वस्तुओं के shareWith में नए रिकॉर्ड को आगे बढ़ाने के लिए।

मैंने कोशिश की:

// 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() }] })

कोई काम नहीं करता। ये क्वेरी मेरे एरे को ओवरराइट करती हैं।

उत्तर सरल हो सकता है, लेकिन मैं इसे नहीं ढूंढ सका ...

धन्यवाद


आप ऐरे को प्राप्त करने के लिए एक लेन-देन ( https://firebase.google.com/docs/firestore/manage-data/transactions ) का उपयोग कर सकते हैं, उस पर पुश करें और फिर दस्तावेज़ को अपडेट करें:

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

ऊपर वर्णित उत्तर के अलावा। यह कर देगा। Angular 5 और AngularFire2 का उपयोग करना। या इस के बजाय firebase.firestore () का उपयोग करें

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

पार्टी के लिए देर से क्षमा करें, लेकिन फायरस्टार ने अगस्त 2018 में इसे वापस हल कर दिया है, इसलिए यदि आप अभी भी यहां देख रहे हैं तो यह सरणियों के संबंध में हल किए गए सभी मुद्दे हैं।

https://firebase.googleblog.com/2018/08/better-arrays-in-cloud-firestore.html https://firebase.googleblog.com/2018/08/better-arrays-in-cloud-firestore.html

सरणी-में, arrayRemove, सरणियों की जाँच, हटाने और अद्यतन करने के लिए arrayUnion है। आशा करता हूँ की ये काम करेगा।


फायरस्टार के अब दो कार्य हैं जो आपको पूरी बात को फिर से लिखने के बिना एक सरणी को अपडेट करने की अनुमति देते हैं।

लिंक: https://firebase.google.com/docs/firestore/manage-data/add-data , विशेष रूप से https://firebase.google.com/docs/firestore/manage-data/add-data#update_elements_in_an_array

एरे में तत्वों को अपडेट करें

यदि आपके दस्तावेज़ में एक सरणी फ़ील्ड है, तो आप तत्वों को जोड़ने और हटाने के लिए arrayUnion () और arrayRemove () का उपयोग कर सकते हैं। arrayUnion () एक सरणी में तत्वों को जोड़ता है लेकिन केवल पहले से मौजूद तत्व नहीं है। arrayRemove () प्रत्येक दिए गए तत्व के सभी उदाहरणों को हटा देता है।


सैम स्टर्न के उत्तर का निर्माण करने के लिए, एक 3 विकल्प भी है जिसने मेरे लिए चीजों को आसान बना दिया है और वह उपयोग कर रहा है जिसे Google एक मैप कहता है, जो अनिवार्य रूप से एक शब्दकोश है।

मुझे लगता है कि आप जिस डिस्क्रिप्शन केस का वर्णन कर रहे हैं, उसके लिए एक शब्दकोश कहीं बेहतर है। मैं आमतौर पर सामान के लिए सरणियों का उपयोग करता हूं जो वास्तव में बहुत अधिक अपडेट नहीं किया गया है, इसलिए वे अधिक या कम स्थिर हैं। लेकिन उन सामानों के लिए जो बहुत कुछ लिखा जाता है, विशेष रूप से ऐसे मान जिन्हें उन क्षेत्रों के लिए अद्यतन करने की आवश्यकता होती है जो डेटाबेस में किसी और चीज़ से जुड़े होते हैं, शब्दकोश बनाए रखना और उनके साथ काम करना बहुत आसान साबित होता है।

तो आपके विशिष्ट मामले के लिए, DB संरचना इस तरह दिखाई देगी:

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

यह आपको निम्नलिखित कार्य करने की अनुमति देगा:

var whoEmail = '[email protected]';

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

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

एक चर के रूप में ऑब्जेक्ट को परिभाषित करने का कारण यह है कि 'sharedWith.' + whoEmail + '.when' का उपयोग 'sharedWith.' + whoEmail + '.when' सेट विधि में सीधे 'sharedWith.' + whoEmail + '.when' परिणामस्वरूप, Node.js क्लाउड फ़ंक्शन में इसका उपयोग करने पर कम से कम त्रुटि होगी।


संपादित करें 08/13/2018 : अब क्लाउड फायरस्टार में देशी सरणी संचालन के लिए समर्थन है। नीचे डग का जवाब देखें।

क्लाउड फायरस्टार में वर्तमान में एकल सरणी तत्व को अपडेट करने (या किसी एकल तत्व को जोड़ने / हटाने) का कोई तरीका नहीं है।

यह कोड यहाँ है:

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

यह दस्तावेज़ को proprietary/docID पर सेट करने के लिए कहता है जैसे कि sharedWith = [{ who: "[email protected]", when: new Date() } लेकिन किसी भी मौजूदा दस्तावेज़ गुणों को प्रभावित नहीं करने के लिए। यह आपके द्वारा दिए गए update() कॉल के समान है, हालांकि set() कॉल के साथ दस्तावेज़ बनाएं अगर यह मौजूद नहीं है तो update() कॉल विफल हो जाएगी।

इसलिए आपके पास दो विकल्प हैं जो आप चाहते हैं।

विकल्प 1 - पूरी सरणी सेट करें

सरणी की संपूर्ण सामग्री के साथ कॉल set() , जिसे पहले DB से वर्तमान डेटा को पढ़ने की आवश्यकता होगी। यदि आप समवर्ती अद्यतनों के बारे में चिंतित हैं, तो आप लेनदेन में यह सब कर सकते हैं।

विकल्प 2 - एक सबकोलेक्शन का उपयोग करें

आप मुख्य दस्तावेज़ के sharedWith को sharedWith कर सकते हैं। तब एक ही आइटम जोड़ना इस तरह दिखेगा:

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

बेशक यह नई सीमाओं के साथ आता है। आप उन दस्तावेजों के आधार पर क्वेरी नहीं कर पाएंगे जिनके साथ वे साझा किए गए हैं, और न ही आप एक ही ऑपरेशन में डॉक्टर और साझा किए गए सभी डेटा प्राप्त कर पाएंगे।





google-cloud-firestore