programing

Firestore로 "오브젝트 배열"을 업데이트하는 방법은 무엇입니까?

i4 2023. 6. 10. 08:19
반응형

Firestore로 "오브젝트 배열"을 업데이트하는 방법은 무엇입니까?

저는 현재 Firestore를 사용하고 있으며, "어레이 업데이트(일명 하위 문서)"라는 매우 간단한 작업에 빠져 있습니다.

제 DB 구조는 매우 간단합니다.예:

proprietary: "John Doe",
sharedWith:
  [
    {who: "first@test.com", when:timestamp},
    {who: "another@test.com", when:timestamp},
  ],

나는 새로운 기록을 (성공하지 못하고) 밀어넣으려고 노력하고 있습니다.shareWith물체의 배열

시도해 봤습니다.

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

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

아무 것도 안 돼요.이 쿼리는 내 배열을 덮어씁니다.

답은 간단할지 몰라도 찾을 수가 없었어요

이제 Firestore에는 전체를 다시 쓰지 않고 어레이를 업데이트할 수 있는 두 가지 기능이 있습니다.

링크: 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()는 지정된 각 요소의 모든 인스턴스를 제거합니다.

2018년 8월 13일 편집:이제 Cloud Firestore에서 기본 어레이 작업을 지원합니다.아래 Doug의 답변을 참조하십시오.


현재 Cloud Firestore에서 단일 어레이 요소를 업데이트하거나 단일 요소를 추가/제거할 수 있는 방법이 없습니다.

다음 코드:

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

이것은 문서를 다음으로 설정하라고 말합니다.proprietary/docID 식으로sharedWith = [{ who: "third@test.com", when: new Date() }기존 문서 속성에 영향을 주지 않습니다.그것은 그것과 매우 비슷합니다.update()를 드렸는데 전화를 드렸어요.set() 가서존않경는문생우다성서니합를문재지하가 있는 통화 중에 call with 합니다.update()호출이 실패합니다.

원하는 것을 달성할 수 있는 두 가지 옵션이 있습니다.

옵션 1 - 전체 배열 설정

set()DB에서 현재 데이터를 먼저 읽어야 하는 배열의 전체 내용을 포함합니다.동시 업데이트가 걱정되는 경우 이 모든 작업을 트랜잭션에서 수행할 수 있습니다.

옵션 2 - 하위 컬렉션 사용

당신은 만들 수 있습니다.sharedWith.그러면 단일 항목을 추가하면 다음과 같습니다.

firebase.firestore()
  .collection('proprietary')
  .doc(docID)
  .collection('sharedWith')
  .add({ who: "third@test.com", when: new Date() })

물론 이것은 새로운 한계를 동반합니다..sharedWith데이터를 한 번에 처리할 수 있습니다.

다음은 Firestore 설명서의 최신 예입니다.

화력 기지소방서필드 값.어레이 유니온

var washingtonRef = db.collection("cities").doc("DC");

// Atomically add a new region to the "regions" array field.
washingtonRef.update({
    regions: firebase.firestore.FieldValue.arrayUnion("greater_virginia")
});

// Atomically remove a region from the "regions" array field.
washingtonRef.update({
    regions: firebase.firestore.FieldValue.arrayRemove("east_coast")
});

트랜잭션(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);
    });

파티에 늦어서 미안하지만 Firestore는 2018년 8월에 해결했기 때문에 여전히 찾고 있다면 어레이와 관련된 모든 문제가 해결되었습니다.

https://firebase.googleblog.com/2018/08/better-arrays-in-cloud-firestore.html공식 블로그 게시물

배열을 확인, 제거 및 업데이트하기 위한 배열 포함, arrayRemove, arrayUnion.도움이 되길 바랍니다.

스턴의 대답을 바탕으로, 제게 더 쉽게 해준 세 번째 옵션이 있습니다. 구글이 지도라고 부르는 것을 사용하는 것은 기본적으로 사전입니다.

저는 당신이 설명하고 있는 사용 사례에 사전이 훨씬 더 좋다고 생각합니다.저는 보통 너무 많이 업데이트되지 않은 항목에 어레이를 사용하기 때문에 다소 정적입니다.그러나 많이 기록되는 항목, 특히 데이터베이스의 다른 항목에 연결된 필드에 대해 업데이트해야 하는 값의 경우 사전을 유지 관리하고 작업하는 것이 훨씬 더 쉽습니다.

따라서 특정 사례의 경우 DB 구조는 다음과 같습니다.

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

이렇게 하면 다음 작업을 수행할 수 있습니다.

var whoEmail = 'first@test.com';

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

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

는 개를변정의이는유다는을 사용하기 입니다.'sharedWith.' + whoEmail + '.when'적어도 Node.js 클라우드 함수에서 set 메서드를 직접 사용하면 오류가 발생합니다.

#편집(설명 추가 :) 기존 파이어스토어 문서 필드를 업데이트할 배열이 있다고 합니다.사용할 수 있습니다.set(yourData, {merge: true} )setOptions(set 함의두번매째개수변전달)를 사용하여 함수의 두 ) {merge: true}덮어쓰는 대신 변경 사항을 병합하려면 이 필요합니다.여기 그것에 대해 공식 문서에 나와 있는 것이 있습니다.

DocumentReference, WriteBatch 및 Transaction에서 set() 호출의 동작을 구성하는 옵션 개체입니다.이러한 호출은 병합과 함께 SetOptions를 제공하여 대상 문서 전체를 덮어쓰는 대신 세분화된 병합을 수행하도록 구성할 수 있습니다.

당신은 이것을 사용할 수 있습니다.

const yourNewArray = [{who: "first@test.com", when:timestamp}
{who: "another@test.com", when:timestamp}]    


collectionRef.doc(docId).set(
  {
    proprietary: "jhon",
    sharedWith: firebase.firestore.FieldValue.arrayUnion(...yourNewArray),
  },
  { merge: true },
);

이것이 도움이 되길 바랍니다 :)

addToCart(docId: string, prodId: string): Promise<void> {
    return this.baseAngularFirestore.collection('carts').doc(docId).update({
        products:
        firestore.FieldValue.arrayUnion({
            productId: prodId,
            qty: 1
        }),
    });
}

우리는 사용할 수 있습니다.arrayUnion({})이를 달성하는 방법.

사용해 보십시오.

collectionRef.doc(ID).update({
    sharedWith: admin.firestore.FieldValue.arrayUnion({
       who: "first@test.com",
       when: new Date()
    })
});

설명서는 https://firebase.google.com/docs/firestore/manage-data/add-data#update_elements_in_an_array 에서 찾을 수 있습니다.

나는 이것이 정말 오래된 것이라는 것을 알지만, 문제를 가진 사람들을 돕기 위해.

Firebase V9는 arrayUnion 및 arrayRemove를 사용하는 솔루션을 제공합니다.

await updateDoc(documentRef, {
    proprietary: arrayUnion( { sharedWith: [{ who: "third@test.com", when: new Date() }] }
});

더 많은 설명을 위해 이것을 확인하세요.

위에 언급된 답변 이외의 답변.이걸로 충분해요.Angular 5 및 Angular Fire2를 사용합니다.또는 화기 기지를 사용합니다.이것 대신에 firestore ().afs.

  // say you have have the following object and 
  // database structure as you mentioned in your post
  data = { who: "third@test.com", 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
    });
 }  

John Do를 모음이 아닌 문서로 간주

다른 사람들과 공유하는 것들의 모음을 제공합니다.

그런 다음 John Doe의 공유 항목을 매핑하고 해당 병렬 항목의 공유 항목을 쿼리할 수 있습니다.

proprietary: "John Doe"(a document)

things(collection of John's things documents)

thingsSharedWithOthers(collection of John's things being shared with others):
[thingId]:
    {who: "first@test.com", when:timestamp}
    {who: "another@test.com", when:timestamp}

then set thingsSharedWithOthers

firebase.firestore()
.collection('thingsSharedWithOthers')
.set(
{ [thingId]:{ who: "third@test.com", when: new Date() } },
{ merge: true }
)

파이어베이스 문서에서 배열을 업데이트하려는 경우.당신은 이걸 할 수 있다.

    var documentRef = db.collection("Your collection name").doc("Your doc name")

    documentRef.update({
yourArrayName: firebase.firestore.FieldValue.arrayUnion("The Value you want to enter")});

비록 ~일지라도firebase.firestore.FieldValue.arrayUnion()를 사용하는 동시에 Firestore에서 어레이 업데이트를 위한 솔루션을 제공합니다.{merge:true}사용하지 않는 경우{merge:true}새 값으로 업데이트하는 동안 문서의 다른 모든 필드가 삭제됩니다.다음은 참조 문서의 데이터를 손실하지 않고 배열을 업데이트하기 위한 작업 코드입니다..set()방법:


const docRef = firebase.firestore().collection("your_collection_name").doc("your_doc_id");

docRef.set({yourArrayField: firebase.firestore.FieldValue.arrayUnion("value_to_add")}, {merge:true});

어레이 필드에 항목을 추가할 Java firestore sdk 솔루션을 찾고 있는 경우:

List<String> list = java.util.Arrays.asList("A", "B");
Object[] fieldsToUpdate = list.toArray();
DocumentReference docRef = getCollection().document("docId");
docRef.update(fieldName, FieldValue.arrayUnion(fieldsToUpdate));

어레이 사용자에서 항목을 삭제하는 방법FieldValue.arrayRemove()

문서에 배열 형식의 중첩된 개체가 있는 경우 .dot 표기법을 사용하여 중첩된 필드를 참조하고 업데이트할 수 있습니다.Node.js 예:

const users = {
  name: 'Tom',
  surname: 'Smith',
  favorites: {
    sport: 'tennis',
    color: 'red',
    subject: 'math'
  }
};

const update = await db.collection('users').doc('Tom').update({
  'favorites.sport': 'snowboard'
});

또는 Android sdk 예:

db.collection("users").document("Tom")
        .update(
               'favorites.sport': 'snowboard'
        );

소방서에는 간단한 해킹이 있습니다.

속성 이름으로 "."가 있는 경로 사용:

propertyname.arraysubname.${id}:

db.collection("collection")
 .doc("docId")
 .update({arrayOfObj: fieldValue.arrayUnion({...item})})

언급URL : https://stackoverflow.com/questions/46757614/how-to-update-an-array-of-objects-with-firestore

반응형