FirebaseV9 쓰기 방법을 사용하여 데이터 가져오기

이 보도에 관하여


2021년 8월 25일 Firebase 버전 9이 발표된 이후 작법이 크게 달라졌다.
이 보도는 v9 업데이트 시 팩스 내용에 대한 비망록입니다.
Firebase에 액세스할 때 Type Script를 ts 파일에 사용합니다.

컨디션

  • Firebase 9.1.3
  • Nuxt.js 2.15.7
  • TypeScript 4.2.4
  • macOS Big Sur 11.5.2
  • 전제 조건


    이유


    Firebase의 v9는 모듈 트리거를 사용합니다.
    v9는 파일 크기를 줄여서 필요한 파일만 가져오는 형식으로 변경합니다.
    이렇게 하면 페이지의 그리기 속도를 가속화할 수 있다.

    이전 쓰기 방식을 9로 업데이트하면 오류가 발생합니다.


    왜 이런 오류가 발생했을까? 함수 기반의 문법으로 변경할 필요가 있기 때문이다.(v8 이전에는 반을 기준으로 기술했다.)
    구체적으로 말하면 Firebase.firestore...의 부분에서 오류가 발생했습니다.

    어쨌든 해결 방법:compot 활용


    한꺼번에 다 v9로 만들기 힘들어!!이러한 사용자를 위해 Firebase도 v8과 호환되는 방법을 준비했다.
    호환성을 유지하기 위해 가져온 부분을 다음과 같이 덮어씁니다.
    getEnableFirebaseData/index.ts
    // firebase/appをインポートしている部分を
    import firebase from "firebase/app";
    
    // compatを追加する
    import firebase from "firebase/compat/app"
    
    우선 오류를 없애려면 추가 compot을 통해 v9를 사용하는 동시에 코드를 바꾸지 않아도 오류를 없앨 수 있다.
    단, 이 방법은 앞으로 발매될 버전(v10 또는 v11)에서 완전히 삭제되며, 공식적으로 통지되었습니다.
    v9로 이전하는 동안의 구제 처리를 위한 것이기 때문에 Firebase를 사용하는 경우 이전기간이 끝나기 전에 팩스를 다시 보내야 합니다.
    이렇게도 오류가 발생하면 어쩔 수 없이 Firebase 버전을 8로 복원하면 오류가 사라집니다.(근본적으로 해결할 수는 없지만...)

    팩스 순서


    다음은 본론.먼저 초기화합니다.
    Firebase App은 다양한 곳에서 사용하는 경우가 많기 때문에 파일을 잘라 공동으로 사용한다.
    components/settings/firebase/index.ts
    import { initializeApp } from "firebase/app";
    
    const firebaseConfig = {
      apiKey: process.env.apiKey,
      authDomain: process.env.authDomain,
      databaseURL: process.env.authDomain,
      projectId: process.env.projectId
    };
    
    const firebaseApp = initializeApp(firebaseConfig);
    
    export { firebaseApp };
    
    export를 통해 다른 파일에서frebaseApp을 사용할 수 있습니다.

    다 받아봐.


    v8의 쓰기
    getEnableFirebaseData/index.ts
    import firebase from "firebase/app";
    import { EnableHogeType } from "types/GetFirebaseDataTypes";
    const TARGET_COLLECTION_NAME = "collection_Firebase_name";
    
    //全て取得
    export default function(
      db: firebase.firestore.Firestore
    ): Promise<EnableHogeType[]> {
      return new Promise((resolve, reject) => {
        const collectionRef = db.collection(TARGET_COLLECTION_NAME);
        collectionRef
          .get()
          .then(function(querySnapshot: firebase.firestore.QuerySnapshot) {
            const ret: EnableHogeType[] = [];
            querySnapshot.forEach(
              (doc: firebase.firestore.QueryDocumentSnapshot) => {
                ret.push(doc.data() as EnableHogeType);
              }
            );
            resolve(ret);
          })
          .catch(function(error) {
            reject(error);
          });
      });
    }
    
    V9 쓰기
    getEnableFirebaseData/index.ts
    import {
      collection,
      getDocs,
      getFirestore,
      query
    } from "firebase/firestore/lite";
    import { EnableHogeType } from "types/GetFirebaseDataTypes";
    import { firebaseApp } from "~/components/settings/firebase";
    
    const TARGET_COLLECTION_NAME = "collection_Firebase_name";
    
    export default async function() {
      try {
        const db = getFirestore(firebaseApp);
        const q = query(collection(db, TARGET_COLLECTION_NAME));
        const querySnapshot = await getDocs(q);
        const ret: EnableHogeType[] = [];
        querySnapshot.forEach(doc => {
          ret.push(doc.data() as EnableHogeType);
        });
        return ret;
      } catch (error) {
        // 何もしない
      }
    }
    
    코드량이 줄어들면서 전체적인 전망이 좋아졌다.
    v9 특징으로만 가져오는 필요한 방법은 Firebase/firestore/lite입니다.
    v8이라면 import firebase from'firebase/app'로서 사용하지 않는 방법을 가져왔지만 v9에서는 getDocs와query 등 필요한 것만 가져와 묶음 사이즈가 줄어들었다.
    import {
      collection,
      getDocs,
      getFirestore,
      query
    } from "firebase/firestore/lite";
    import { firebaseApp } from "~/components/settings/firebase";
    
    데이터를 얻는 방법에 대해 소장 지정은query 방법을 사용하고db를 첫 번째 파라미터로 지정하며 소장 이름을 두 번째 파라미터로 지정한다.
    const q = query(collection(db, TARGET_COLLECTION_NAME));
    
    Firebase에서 데이터를 얻는 부분은 getDocs 방법입니다.비동기 처리는 공식적인 쓰기 방법을 참고하여 async await를 사용했다.
    또한 공식 문서에 기재되지 않았지만 오류 처리는try,catch에서 추가로 처리됩니다.
    export default async function() {
      try {
        const db = getFirestore(firebaseApp);
        const q = query(collection(db, TARGET_COLLECTION_NAME));
        const querySnapshot = await getDocs(q);
        const ret: EnableHogeType[] = [];
        querySnapshot.forEach(doc => {
          ret.push(doc.data() as EnableHogeType);
        });
        return ret;
      } catch (error) {
        // 何もしない
      }
    }
    
    얻은 정보를 되돌려 다른 파일에서 이 함수를 실행하면 얻을 수 있다.
    위에 빈 배열ret을 준비했습니다. 리턴ret로 돌려주십시오.

    이용시


    예를 들어, Nuxt입니다.js의 경우 함수를 가져오고 실행하면 OK입니다.
    이 일대는 v8과 다름없다.
    파일 이름
    import getFirebase from "~/getEnableFirebaseData" // firebaseのfileをインポート
    <script>
     methods: {
       getEnable: function(){
         getFirebase()
          .then(list => {
    	 // firebaseで取得した情報が入ってくる
          })
          .catch(e => {
    	 // エラーの際の処理
          })
       }
     }
    </script>
    
    이런 느낌으로 다시 써서 Firebase에서 데이터를 얻었다.
    v9라도 where조건 등 상세조건에 부합되는 방법을 준비해 위와 같은 기술을 통해 팩스를 할 수 있습니다.이런 느낌.
    getEnableFirebaseData/index.ts
    import { collection, query, where, getDocs } from "firebase/firestore";
    
    const q = query(collection(db, TARGET_COLLECTION_NAME), where("name", "==", true));
    

    상응하는 id의 하위 모음집에서 데이터 가져오기


    v8의 쓰기
    getEnableFirebaseData/index.ts
    import firebase from "firebase/app";
    import { HogehogeType } from "types/GetFirebaseDataTypes";
    
    export default function(
      db: firebase.firestore.Firestore,
      clientId: string
    ): Promise<HogehogeType | {}> {
      return new Promise((resolve, reject) => {
        if (clientId) {
          const collectionRef = db
            .collection(TARGET_COLLECTION_NAME)
            .doc(clientId)
            .collection(SUB_COLLECTION_NAME);
          collectionRef
            .orderBy("updateAt", "desc")
            .limit(1)
            .get()
            .then(function(querySnapshot: firebase.firestore.QuerySnapshot) {
              let ret: HogehogeType | {} = {};
              querySnapshot.forEach(
                (doc: firebase.firestore.QueryDocumentSnapshot) => {
                  ret = doc.data() as HogehogeType;
                }
              );
              resolve(ret);
            })
            .catch(function(error) {
              reject(error);
            });
        } else {
          resolve({});
        }
      });
    }
    
    상응하는 모음집(위는 id)에서 하위 모음집의 최신 데이터를 얻었습니다.
    V9 쓰기
    getEnableFirebaseData/index.ts
    import {
      collection,
      doc,
      getDocs,
      getFirestore,
      limit,
      orderBy,
      query
    } from "firebase/firestore/lite";
    import { HogehogeType } from "types/GetFirebaseDataTypes";
    import { firebaseApp } from "~/components/settings/firebase";
    
    const TARGET_COLLECTION_NAME = "hogegogeCollection";
    const SUB_COLLECTION_NAME = "historyCollection";
    const db = getFirestore(firebaseApp);
    
    export default async function(clientId: string) {
      try {
        if (clientId) {
          const docRef = doc(db, TARGET_COLLECTION_NAME, clientId);
          const q = query(
            collection(docRef, SUB_COLLECTION_NAME),
            orderBy("updateAt", "desc"),
            limit(1)
          );
    
          const querySnapshot = await getDocs(q);
          let ret: HogehogeType | {} = {};
          querySnapshot.forEach(doc => {
            ret = doc.data() as HogehogeType;
          });
          return ret;
        }
      } catch (error) {
        // 何もしない
      }
    }
    
    하위 모음집을 지정할 때 지정한 모음집 이름을 지정하고query 방법을 통해 가져옵니다.
    getEnableFirebaseData/index.ts
    const docRef = doc(db, TARGET_COLLECTION_NAME, clientId);
    

    최후


    학급기초에서 함수기초로 바뀌어 쓰기 방법도 바뀌어 처음에는 당혹스러웠지만, 습관이 되면서 코드량도 줄어 읽기 쉬워졌다.
    버전이 아직 바뀌지 않았고 날이 아직 지나지 않았기 때문인지 공식 문서의 참고 코드가 더욱 충실해지면 더욱 쉽게 실현될 수 있을까?내 생각엔

    참고 자료


    공식 문서에 약간의 v9 샘플 코드가 실렸다.
    https://firebase.google.com/docs/firestore/query-data/get-data?hl=ja#web-version-9_1

    좋은 웹페이지 즐겨찾기