Firebase가 데이터로드 (vue)를 완료 할 때까지 기다림 / 'await'가 작동하지 않음

Jan 11 2021

내 vue 앱에서 created-hook의 firebase에서 일부 데이터를 가져옵니다 . 데이터로드가 완료된 후 나중에 코드를 제외하고 싶습니다. 그러나 나는 그것을 작동시킬 수 없습니다.

내 코드는 다음과 같습니다.

<template>
    <div>
        <h1>Test 2</h1>
    </div>
</template>

<script>
import { institutesCollection } from '../firebase';
export default {
    name: 'Test2',
    data() {
        return {
            settings: null,
        }
    },
    async created() {
        await institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(
            await function(doc) {
                this.settings = doc.data();
                console.log(this.settings);
            }
        )
        console.log('Done with fetching Data');
        console.log(this.settings)
    },
    methods: {
        
    }
}
</script>

그러나 하나의 콘솔이 먼저 'Done with fetching Data'표시되고 그 다음 null( this.settings아직 이므로 null) Objekt settings가 인쇄됩니다. 그러나 this.settings거기 null에서 일하기 위해서는 더 이상이 아닌 거기에서 정의 되어야 합니다 .

지금까지 시도한 것 :

  1. 넣기 기다립니다
  2. 로드 추가 parameter
  3. 나중에 코드 추가 then()

아무것도 작동하지 않았습니다.

답변

3 RenaudTarnec Jan 11 2021 at 00:56

onSnapshot()방법은 비동기 방식이 아니다. 문서에서 설명했듯이 " DocumentSnapshot이벤트에 대한 리스너를 연결 "합니다.

따라서 Firestore 문서에 연속 리스너설정 하려면이를 사용해야합니다 . 문서에서 무언가 변경되면 (예 : 필드가 새 값을 가져옴) 리스너가 트리거됩니다. "제공 한 콜백을 사용하는 초기 호출은 단일 문서의 현재 내용으로 즉시 문서 스냅 샷을 만듭니다"( doc 참조 ).

onSnapshot()다음과 같이에 전달하는 콜백 함수에서만 Firestore 문서 데이터를 가져옵니다 .

created() {
    institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(doc => {
           this.settings = doc.data();
           console.log(this.settings);
      });
}

Nilesh Patel이 언급했듯이이 콜백 에서 사용하려면 화살표 함수를 사용해야합니다this . 또한 created함수 가 비동기 일 필요는 없습니다 .

마지막으로 onSnapshot()Vue.js 구성 요소를 삭제할 때 반환되는 구독 취소 함수를 호출하는 것이 좋습니다 . beforeDestroy다음과 같이 후크를 사용하십시오 .

// ...
data() {
    return {
        settings: null,
        firestoreListener: null
    }
},
created() {
    this.firestoreListener  = institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(doc => {
           this.settings = doc.data();
           console.log(this.settings);
      });
},
beforeDestroy() {
  if (this.firestoreListener) {
    this.firestoreListener();
  }
},

반면에, 당신은 단지 문서 데이터를 읽으려면 한 번만 생성 Vue.js 후크에, 당신이 사용해야하는 get()방법을, 같은 다음과 같습니다 :

async created() {
    const doc = await institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').get();
    if (doc.exists) {
             this.settings = doc.data();
    } else {
             // doc.data() will be undefined in this case
             console.log("No such document!");
    }
}

이 경우, 주 created기능 NEEDSasync있으므로, get()비동기식이다.


사이의 차이에 대한 자세한 내용 get()onSnapshot()이에 SO 답변 .

1 NileshPatel Jan 11 2021 at 00:46

화살표 기능을 사용해보십시오

  async created() {
        await institutesCollection.doc('FbdYJ5FzQ0QVcQEk1KOU').onSnapshot(
            doc => {
                this.settings = doc.data();
                console.log(this.settings);
            }
        )
        console.log('Done with fetching Data');
        console.log(this.settings)
  },