programing

파이어스토어 문서에서 중첩된 오브젝트의 필드를 업데이트하시겠습니까?

lastcode 2023. 7. 21. 21:38
반응형

파이어스토어 문서에서 중첩된 오브젝트의 필드를 업데이트하시겠습니까?

데이터 구조는 다음과 같습니다.

enter image description here

"first" 객체의 "test" 키 값을 편집하고 싶습니다.저는 https://firebase.google.com/docs/firestore/manage-data/add-data 에 있는 문서를 따라갔습니다.

하지만 그것은 저에게 효과가 없었습니다.

nodejs 코드:

var setAda = dbFirestore.collection('users').doc('alovelace').update({
        first : {
            test: "12345"
            }
});

화재 저장소의 결과:

"test2" 키가 사라졌습니다.하지만 "test" 값만 업데이트하고 "test2"를 유지하고 싶습니다.

이 문제에 대한 해결책이 있습니까?

제공한 링크에 따르면 다음과 같이 표시됩니다.

문서에 중첩된 오브젝트가 있는 경우, update()를 호출할 때 "도트 표기법"을 사용하여 문서 내의 중첩된 필드를 참조할 수 있습니다.

따라서 다음을 사용해야 합니다.dot notation다음과 같이 덮어쓰지 않고 하나의 필드만 업데이트할 수 있습니다.

var setAda = dbFirestore.collection('users').doc('alovelace').update({
    "first.test": "12345"
});

그러면 다음을 얻게 됩니다.

 first
  test: "12345"
  test2: "abcd"

피터의 해결책은 훌륭하지만 동적 키로는 작동하지 않습니다.다음 코드를 사용할 수 있습니다.

var nestedkey = 'test';
var setAda = dbFirestore.collection('users').doc('alovelace').update({
    [`first.${nestedkey}`]: "12345"
});

'첫 번째' 필드가 없는 경우 발생하는 예외를 원하지 않는 경우 다음을 사용해 보십시오.set와 함께{merge: true}대신 옵션update.

var setAda = dbFirestore.collection('users').doc('alovelace').set({
        first : {
            test: "12345"
        }
}, {merge: true});

편집:

@ShaneWalker 덕분에 파이어스토어의 최신 버전(9.8.1)이 변경되어 다음과 같이 변경되었습니다.update와 동일하게 작동함set와 함께{merge: true}선택.

Firebase JavaScript SDK 릴리스 정보

누군가가 TypeScript를 사용하는 경우(: Cloud 함수)에는 점 표기법으로 중첩된 필드를 업데이트하는 코드가 있습니다.

var setAda = dbFirestore.collection('users').doc('alovelace').update({
    `first.${variableIfNedded}.test`: "12345"
});

사용해 보십시오.그렇게 작동합니까?

var setAda = dbFirestore.collection('users').doc('alovelace').update({
        "first.test" : "12345"
});

좀 더 일반적이고 재귀적인 것이 필요한 사람들을 위해, Foo Firestore 문서를 텍스트 부분으로 파괴적이지 않게 업데이트하는 기능이 있습니다.

private objectToDotNotation(obj: Partial<Foo>, parent = [], keyValue = {}) {
    for (let key in obj) {
        let keyPath = [...parent, key];
        if (obj[key]!== null && typeof obj[key] === 'object')
            Object.assign(keyValue, this.objectToDotNotation(obj[key], keyPath, keyValue));
        else
            keyValue[keyPath.join('.')] = obj[key];
    }
    return keyValue;
}

public update(foo: Partial<Foo>) {
    dbFirestore.collection('foos').doc('fooId').update(
        this.objectToDotNotation(foo)
    )
}

사용set함수와 패싱merge: true다른 필드를 덮어쓰지 않고 깊이 중첩된 필드를 업데이트하는 옵션입니다.

const firstore = firebase.firestore()
const ref = firestore.doc('users/alovelace').set({
  first : {
    test: "12345"
  }
}, { merge: true })

이 방법을 사용하면 필드가 20단계 깊이에 묻혀 있더라도 필드를 업데이트할 수 있습니다.

스위프트 4용

let dictionary:[String:Any] = ["first.test" : "12345"]
let plansDocumentReference = Firestore.firestore().collection("users").document("alovelace")              
plansDocumentReference.updateData(dictionary) { err in
                if let err = err {
                    print("Error updating document: \(err)")

                }}

사전에 레코드를 추가하여 여러 필드를 업데이트하고 사전의 고정 텍스트를 문자열 변수로 대체하여 변수 기반 하위 키를 작성할 수 있습니다.

이 기술은 또한 사전을 모든 키의 값으로 사용하여 문서의 전체 단일 키 하위 블록을 대체합니다.

저는 타입 완성을 염두에 두고 여분의 매개변수가 없는 타입스크립트 버전을 찾고 있었습니다.결국 다음과 같은 결과가 되었습니다.

TS 플레이그라운드 예제

function objectToDotNotation(obj: any): any {

    return Object.keys(obj).reduce( (dnObj, key) => {
        const value = obj[key];

        if (value !== null && typeof value === 'object') {            
            const childObj = objectToDotNotation(value);

            Object.keys(childObj).forEach( childKey => {
                dnObj = {...dnObj, [`${key}.${childKey}`]: childObj[childKey] };
            });
        } else {            
            dnObj = {...dnObj, [key]: value };
        }

        return dnObj;
    }, {});
}

언급URL : https://stackoverflow.com/questions/49150917/update-fields-in-nested-objects-in-firestore-documents

반응형