Firestore Node.보안 유지를 위한 Wrap js SDK CRUD

개요


Firestore SDK의set, 무섭죠.insert라고 생각해서 존재하는 id를 잘못 알았다면, 어떤 소리도 내지 않고 문서를 밟아서 망가뜨리지 않았을 것입니다.만약 이미 존재한다면, 나는 잘못된 함수를 원한다.
나도 귀환치가 Promise<void>인 게 마음에 든다.결과를 삽입한 대상이 돌려주기를 원하는 파이입니다. ({success:true} 같은 것도 가능합니다.)
이 때문에 파이어스토어의 크루드를 Wrap으로 진행한다는 기사다.

손이 가려운 데에 닿지 않는다


Firestore와 SQL(MySQL)의 INSERT/UPDAATE 주위의 방법을 참고로 합니다.
function
문서가 없습니다.
문서 존재
이상 01 명
firestore set
낳다
덮어쓰다
firestore set({merge: true})
낳다
field 업데이트(깊이)
UPSERT
firestore update
잘못
field 업데이트 (얕음)
firestore add
생성(자동 번호 지정)
-
SQL INSERT
낳다
(동일) 생성
SQL INSERT with PRIMARY KEY
낳다
잘못
INSERT
SQL UPDATE
아무 일도 없었어요.
field 업데이트
잘못
field 업데이트(깊이)
UPDATE
혼돈
내가Firestore의 읽기와 쓰기에 필요한 것은'이상'에 적힌 것이다.
이를 실현하기 위해 wrap을 만들어 각종 함수의 최강 함수를 만들어 봤다.
!
api를 여러 번 쳐서 거래 문제가 생겼는데 다 무시했어요.빈도가 높을 때 주의하세요.
!
내가 사용하는 것은 Firebase-admin SDK의 Firestore인데,client용 (WEB)의 SDK와는 좀 다르다.admin의 쓰기 방법은 웹의 v8과 같지만 v8이 지원을 종료하기로 결정됨이기 때문에 v9로 이동하는 것을 권장합니다.client로 사용할 때 v9의 기법doc.exists으로 수정하고 함수화하십시오. 주의하십시오)

이루어지다


get


먼저 wrapget의 함수를 썼다.제네릭스type T는 대상 속성id(분리가 귀찮아서)(원래 id라는 속성이 있으면 문제없음)을 결정했다.
또한 get에 doc가 없을 때null가 되돌아옵니다.
export const getDocument = async <T>(collection: string,  documentId: ID, firestore: any) : Promise<T> => {
    const ref = firestore.collection(collection).doc(documentId);
    const data = await ref.get().then((doc: any) => {
        if (doc.exists) {
            const docData = doc.data();
            docData.id = doc.id;
            return docData;
        }else{
            return null
        }
    }).catch(function(error: any) {
        console.log("Error getting document: ", error);
    });
    return data;
}

INSERT

get->set->get의 순서대로 세 번 두드린다.호출 횟수가 늘어나는 것도 어쩔 수 없다.
transaction을 무시합니다.set({merge: true}) 그래서 써도 위험하지 않아요.
/**
 * INSERT (ない時作成、ある時エラー、返り値はINSERTされた値)
 * @param collection 
 * @param documentId 
 * @param object 
 * @param firestore 
 */
export const insertDocument = async <T>(collection: string, documentId: string, object: object, firestore: Firestore) : Promise<T> => {
    const ref = await firestore.collection(collection).doc(documentId);
    await ref.get().then(async (doc: any) => {
        if (doc.exists) {
            throw documentId + " already exists.";
        } else {
            return await ref.set(object, {merge: true});
        }
    }).catch(function(error: string) {
        throw error;
    });
    return await getDocument<T>(collection, documentId, firestore);
}

INSERT(자동 번호)

add 문서 ID를 자동으로 생성할 수 있어 매우 편리합니다.
/**
 * INSERT (自動採番、返り値はINSERTされた値(id付き))
 * @param collection 
 * @param object 
 * @param firestore 
 */
export const autoInsertDocument = async <T>(collection: string, object: Omit<T, "id">, firestore: Firestore) : Promise<T> => {
    const ref = await firestore.collection(collection).add(object);
    const res = await ref.get().then(async (doc: any) => {
        const data = Object.assign(doc.data(), {id: doc.id})
        return data
    }).catch(function(error: string) {
        throw error;
    });
    return res;
}

UPDATE


이것도 update 사용하지 않습니다set({merge: true}).전자는 얕은 갱신이 있고, 후자는 깊은 갱신의 차이가 있다.
https://tomokazu-kozuma.com/difference-between-set-and-update-when-updating-cloud-firestore-data/
/**
 * UPDATE (ない時エラー、ある時深いfield更新、返り値はUPDATEされた値)
 * @param collection 
 * @param documentId 
 * @param updates 
 * @param firestore 
 */
export const updateDocument = async <T>(collection: string, documentId: ID, updates: object, firestore: Firestore) : Promise<T> => {
    const ref = firestore.collection(collection).doc(documentId);
    await ref.get().then(async (doc: any) => {
        if (doc.exists) {
            return await ref.set(updates, {merge: true});
        } else {
            throw documentId + " does not exist.";
        }
    }).catch(function(error: string) {
        throw error;
    });
    return await getDocument<T>(collection, documentId, firestore);
}

UPSERT


'UPDATE가 있고 INSERT가 없다'는 UPERT라는 이름이 있다.
이것은 완전히 set({merge: true}) 이다.
/**
 * UPSERT (ない時作成、ある時深いfield更新、返り値はUPSERTされた値)
 * @param collection 
 * @param documentId 
 * @param updates 
 * @param firestore 
 */
export const upsertDocument = async <T>(collection: string, documentId: ID, updates: object, firestore: Firestore) : Promise<T> => {
    const ref = firestore.collection(collection).doc(documentId);
    await ref.set(updates, {merge: true});
    return await getDocument<T>(collection, documentId, firestore);
}

DELETE

delete 문서가 존재하지 않아도 오류가 발생하지 않습니다. 싫기 때문에 존재하는 것을 확인한 후에 두드려야 합니다.
https://stackoverflow.com/questions/53251138/firebase-firestore-returning-true-on-failed-document-delete
/**
 * DELETE (ない時エラー、ある時削除、返り値は消される前の値)
 * @param collection 
 * @param documentId 
 * @param firestore 
 */
export const deleteDocument = async <T>(collection: string, documentId: ID, firestore: Firestore) : Promise<T> => {
    const ref = firestore.collection(collection).doc(documentId);
    await ref.get().then(async (doc: any) => {
        if (doc.exists) {
            ref.delete();
            return await doc.data();
        } else {
            throw documentId + " does not exist.";
        }
    }).catch(function(error: string) {
        throw error;
    });
    return await getDocument<T>(collection, documentId, firestore);
}

총결산

  • 사용하기 어려운 함수를 wrap한다.
  • 다음은 SQL 편입니다.
  • 좋은 웹페이지 즐겨찾기