반응형
Angular에서 Firebase Cloud Firestore의 Transaction 기능을 좀 더 효과적으로 활용하고자 할 때 참고 바랍니다.
import { AngularFirestore } from '@angular/fire/firestore';
import * as firebase from 'firebase';
export const dbRootPath: string = "rootPath";
// 트랜잭션 타입 정의
enum transactionType { "set", "update", "delete" };
type TransactionType = keyof typeof transactionType;
// 트랜잭션 아이템 정의
export interface TransactionItem {
type: TransactionType,
path: string,
key: string,
data?: any,
returnKey?: boolean,
escapeValue?: string
}
// 트랜잭션 정의
export interface Transaction {
path: string,
key: string,
transactionItem: TransactionItem[],
transactionExpandItem?: TransactionItem[]
}
export class FirebaseTransaction {
constructor(private afs: AngularFirestore) { }
//트랜잭션 처리 함수
async transaction(transactionList: Transaction[]) {
try {
let retKeyVal: string[] = [];
await this.afs.firestore.runTransaction(async (transaction: firebase.firestore.Transaction) => {
let docList: firebase.firestore.DocumentSnapshot[] = [];
let tempKey: string = null;
for (let i = 0; i < transactionList.length; i++) {
docList.push(await transaction.get(this.afs.firestore.collection(dbRootPath + '/' + transactionList[i].path).doc(transactionList[i].key)))
}
for (let i = 0; i < transactionList.length; i++) {
transactionList[i].transactionItem.forEach(item => {
const _path = dbRootPath + '/' + item.path;
const _equalKey = '=';
let _key: string;
if (item.key == _equalKey) { // 직전 액션과 동일한 키 사용이 필요한 경우
_key = tempKey;
} else if (item.key && !'') {
_key = item.key;
} else {
_key = this.afs.createId();
}
// 기존 키 임시 저장
tempKey = _key;
if (item.type == "set") {
transaction.set(
this.afs.firestore.collection(_path).doc(_key),
item.data
);
// returnKey true일 경우 값 저장
if (item.returnKey) {
retKeyVal.push(_key);
} else {
retKeyVal.push(null);
}
} else if (item.type == "update") {
if (item.data) {
transaction.update(
this.afs.firestore.collection(_path).doc(_key),
item.data
);
}
} else if (item.type == "delete") {
transaction.delete(
this.afs.firestore.collection(_path).doc(_key)
)
}
});
if (transactionList[i].transactionExpandItem) {
transactionList[i].transactionExpandItem.forEach(item => {
// returnKey와 연계작업을 위한 처리
const _escapeValue = item.escapeValue || '?';
const _path = dbRootPath + '/' + item.path.replace(_escapeValue, retKeyVal[i]);
const _equalKey = '=';
let _key: string;
if (item.key == _equalKey) { // 동일한 키 사용이 필요한 경우 반드시 대상 신규 키(공백) 다음에 위치해야 함
_key = tempKey;
} else if (item.key && !'') {
_key = item.key.replace(_escapeValue, retKeyVal[i]);
} else {
_key = this.afs.createId();
}
// 기존 키 임시 저장
tempKey = _key;
//data 부분 키값 처리
for (let key in item.data) {
if (item.data[key] === _escapeValue) {
item.data[key] = item.data[key].replace(_escapeValue, retKeyVal[i]);
}
}
if (item.type == "set") {
transaction.set(
this.afs.firestore.collection(_path).doc(_key),
item.data
);
} else if (item.type == "update") {
if (item.data) {
transaction.update(
this.afs.firestore.collection(_path).doc(_key),
item.data
);
}
} else if (item.type == "delete") {
transaction.delete(
this.afs.firestore.collection(_path).doc(_key)
)
}
});
}
}
});
return retKeyVal;
} catch (error) {
throw error;
}
}
}
반응형
'프로그래밍 & IT 정보 > Etc.' 카테고리의 다른 글
React Redux 효율적인 공부 방법 (0) | 2022.02.27 |
---|---|
리액트(React) 완성도 높은 초보 온라인 무료 강의 추천 (0) | 2022.02.24 |
인공지능, 머신러닝, 딥러닝 다 같은 말 아닌가요? 간단한 개념 설명 (1) | 2022.01.17 |
[SVG] animateTransform 2가지 동시 적용 (0) | 2020.07.04 |
[Ionic4] ion-select customizing(커스터마이징) 방법 (0) | 2020.07.04 |
[Ionic4] Scroll Event를 활용한 데이터 추가 로딩 방법 (0) | 2020.07.03 |
[Ionic4] Android MainActivity.java 변경 필요 시 적용 방법 (0) | 2020.07.03 |
[Firebase/Angular] Cloud Firestore Pagination Query Example (0) | 2020.07.03 |
댓글