Pinia의 state와 Firestore를 간단히 동기화하는 pinia-plugen-firestore sync
npm
창고는 여기 있습니다(🌟선물받을 수 있으면 기쁘겠다!
모티프
Pinia와 Firestore 두 개는 개발 효율을 대폭 높일 수 있는 우수한 라이브러리와 데이터베이스이지만 Pinia의state와Firestore의 문서를 동기화하려면
onSnapShot
를 사용해야 한다.
export const useExampleStore = defineStore('expamle', {
state: {/*...*/}
actions: {
async setup() {
// ...
//🌟 docDataとdocRefを同期
onSnapshot(docRef, (ds) => {
if (ds.exists()) {
this.$patch({ docData: ds.data() })
}
})
}
}
})
이것onSnapshot
은 개발된 것과 같은 처리를 여러 곳에서 여러 번 써야 하기 때문에 더 이상 DRY가 아니다.또 하나의 스토어에서 여러 개의 Doctoment와 동기화하려면 세로로 몇 번 써야 한다. 너무 지루하고 전망도 나쁘다.
단순히 피니아의 스테이트와 파이어스토어의 문서를 동기화하고 싶었을 뿐인데 내부에 대한 자세한 사정을 너무 많이 알고 있어 역겹다.
async setup() {
// 何回もonSnapshotを書く必要があり、めちゃくちゃ冗長に😱
onSnapshot(docRefA, (ds) => {
if (ds.exists()) {
this.$patch({ docDataA: ds.data() })
}
})
onSnapshot(docRefB, (ds) => {
if (ds.exists()) {
this.$patch({ docDataB: ds.data() })
}
})
onSnapshot(docRefC, (ds) => {
if (ds.exists()) {
this.$patch({ docDataC: ds.data() })
}
})
}
그래서 이 문제를 해결하기 위해 만들었다pinia-plugin-firestore-sync
.이 플러그인을 사용하면 방금 전의 코드가 매우 간단해질 것입니다.스케줄러🙌)
async setup() {
// やったね🙌
this.sync('docDataA', docRefA)
this.sync('docDataB', docRefB)
this.sync('docDataC', docRefC)
}
사용법
README에도 같은 기록이 있는데 여기도 일본어로 소개합니다.
플러그인 먼저 설치
npm install pinia-plugin-firestore-sync
use
를 사용하여 플러그 인을 추가합니다.import { PiniaFirestoreSync } from 'pinia-plugin-firestore-sync'
// プラグインを追加
const pinia = createPinia().use(firestoreSyncPlugin)
app.use(pinia).mount('#app')
문서와 동기화할 때
동기화하려는 Pinia의 속성 이름을 첫 번째 매개변수에, Docoment Reference를 두 번째 매개변수에 각각 지정하여 쉽게 동기화할 수 있습니다.
this.sync(
'docData', // Document Dataと同期させたいpiniaのプロパティ名
docRef // Document Reference
)
샘플 코드import { doc, getFirestore } from "firebase/firestore"
import { defineStore } from "pinia"
type ExampleDoc = {
name: string,
age: number
}
export type State = {
docData: ExampleDoc | null,
}
export const useExampleStore = defineStore('expamle', {
state: (): State => {
return {
docData: null,
}
},
actions: {
async setup() {
// Get Document reference
const store = getFirestore()
const docRef = doc(store, 'Examples/id')
// Do the magic
this.sync('docData', docRef)
}
}
})
모음과 동기화할 때
모음을 동기화할 수도 있습니다.
이 또한 동기화하려는 Pinia의 속성 이름을 첫 번째 매개변수에, Collection Reference를 두 번째 매개변수에 지정할 뿐입니다.간단하네요!
this.sync(
'collectionData' // Collection Dataと同期させたいpiniaのプロパティ名
collectionRef // Collection Reference
)
샘플 코드import { collection, getFirestore } from "firebase/firestore"
import { defineStore } from "pinia"
type ExampleDoc = {
name: string,
age: number
}
export type State = {
collectionData: ExampleDoc[] | null,
}
export const useExampleStore = defineStore('expamle', {
state: (): State => {
return {
collectionData: null,
}
},
actions: {
async setup() {
// Get Collection reference
const store = getFirestore()
const collectionRef = collection(store, 'Examples')
// Do the magic
this.sync('collectionData', collectionRef)
}
}
})
질의와 동기화할 때
질의를 동기화할 수도 있습니다.
나는 네가 이미 알고 있다고 생각한다. 단지 동기화하고 싶은 Pinia의 속성 이름을 첫 번째 파라미터에 맡기고, Collection Reference는 두 번째 파라미터에 맡길 뿐이다.예상대로 웃네요.
this.sync(
'queryData' // Collection Dataと同期させたいpiniaのプロパティ名
query // Query
)
샘플 코드import { collection, getFirestore, query, where } from "firebase/firestore"
import { defineStore } from "pinia"
type ExampleDoc = {
name: string,
age: number
}
export type State = {
queryData: ExampleDoc[] | null,
}
export const useExampleStore = defineStore('expamle', {
state: (): State => {
return {
queryData: null,
}
},
actions: {
async setup() {
// Build query
const store = getFirestore()
const collectionRef = collection(store, 'Examples')
const q = query(collectionRef, where('name', '==', 'wombat'))
// Do the magic
this.sync('queryData', q)
}
}
})
내부 구조
내부 구조에 신경 쓰는 분들도 계실 것 같아서 간단하게 소개해 드리겠습니다.
우선, Pinia는 다음과 같은 방법플러그 인을 통해 스토어에서 공통된 방법과 속성을 간단하게 생성할 수 있다.
import { PiniaPluginContext } from "pinia";
// プラグイン
const magicNumPlugin = ({ store }: PiniaPluginContext) => {
store.magicNumber = 5
}
// 型付
declare module 'pinia' {
export interface PiniaCustomProperties {
magicNumber: number
}
export interface DefineStoreOptionsBase<S, Store> {
}
이 구조를 이용하여 성장sync
.30줄 정도의 아주 짧은 코드.
import { CollectionReference, DocumentReference, onSnapshot, Query, Unsubscribe } from "firebase/firestore";
import { PiniaPluginContext } from "pinia";
export const PiniaFirestoreSync = ({ store }: PiniaPluginContext) => {
store.sync = (key, ref) => {
// Document
if (ref instanceof DocumentReference) {
return onSnapshot(ref, (ds) => {
if (ds.exists()) {
store.$patch({ [key]: ds.data() })
}
})
}
// Collection or Query
return onSnapshot(ref, (qs) => {
const datum = qs.docs.map(d => d.data())
store.$patch((state) => {
state[key] = datum
})
})
}
}
declare module 'pinia' {
export interface PiniaCustomProperties<Id, S, G, A> {
sync(key: string, ref: DocumentReference): Unsubscribe
sync(key: string, ref: CollectionReference): Unsubscribe
sync(key: string, ref: Query): Unsubscribe
}
}
onSnapShot과 같은 방법명으로 Doocument/Collection/Query를 모두 납품하고자 하기 때문에 납품의 유형에 따라 내부에if분할을 진행한다.store.sync = (key, ref) => {
// Document
if (ref instanceof DocumentReference) {
return onSnapshot(ref, (ds) => {
if (ds.exists()) {
store.$patch({ [key]: ds.data() })
}
})
}
// Collection or Query
return onSnapshot(ref, (qs) => {
const datum = qs.docs.map(d => d.data())
store.$patch((state) => {
state[key] = datum
})
})
}
그런 다음 인터페이스에 전달될 수 있는 유형을 Overload 형식으로 정의합니다.declare module 'pinia' {
export interface PiniaCustomProperties<Id, S, G, A> {
sync(key: string, ref: DocumentReference): Unsubscribe
sync(key: string, ref: CollectionReference): Unsubscribe
sync(key: string, ref: Query): Unsubscribe
}
}
string을 State의 속성에 한정하고 싶은데 어떻게 하는지 모르겠어요. 아시는 분 있으면 알려주세요.🙏이상, pinia의 플러그인은 아직 공개되지 않았습니다. 여러분도 도전해 보세요!
Reference
이 문제에 관하여(Pinia의 state와 Firestore를 간단히 동기화하는 pinia-plugen-firestore sync), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/kazuwombat/articles/d533f17798a894텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)