รอจนกระทั่ง firebase โหลดข้อมูลเสร็จ (vue) / 'await' ไม่ทำงาน

Jan 11 2021

ในแอป vue ของฉันฉันกำลังดึงข้อมูลบางอย่างจากcreatedfirebase ใน-hook ฉันต้องการให้โค้ดดังกล่าวถูกดำเนินการในภายหลังหลังจากโหลดข้อมูลเสร็จแล้ว แต่ฉันไม่สามารถทำให้มันทำงานได้

นี่คือรหัสของฉัน:

<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) และหลังจากนั้นsettingsจะพิมพ์Objekt เท่านั้น แต่ฉันต้องthis.settingsถูกกำหนดไว้ที่นั่น (ไม่ใช่nullอีกต่อไป) เพื่อทำงานกับที่นั่น

สิ่งที่ฉันพยายามจนถึงตอนนี้:

  1. รอคอย
  2. การเพิ่มไฟล์ parameter
  3. การเพิ่มรหัสในภายหลังในไฟล์ then()

ไม่มีอะไรทำงาน

คำตอบ

3 RenaudTarnec Jan 11 2021 at 00:56

onSnapshot()วิธีการไม่ได้เป็นวิธีการที่ไม่ตรงกัน ตามที่อธิบายไว้ในเอกสารคือ "แนบฟังDocumentSnapshotเหตุการณ์"

ดังนั้นคุณควรใช้หากคุณต้องการตั้งค่า Listener ต่อเนื่องให้กับเอกสาร Firestore: หากมีการเปลี่ยนแปลงบางอย่างในเอกสาร (เช่นฟิลด์ได้รับค่าใหม่) ตัวฟังจะถูกทริกเกอร์ โปรดทราบว่า "การโทรครั้งแรกโดยใช้การโทรกลับที่คุณระบุจะสร้างสแนปชอตของเอกสารทันทีพร้อมกับเนื้อหาปัจจุบันของเอกสารเดียว" (ดูเอกสาร )

คุณได้รับข้อมูลเอกสาร Firestore เฉพาะในฟังก์ชันการโทรกลับที่คุณส่งผ่านไปonSnapshot()ดังต่อไปนี้:

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

ดังที่ Nilesh Patel กล่าวไว้โปรดทราบว่าคุณต้องใช้ฟังก์ชันลูกศรเพื่อใช้thisในการโทรกลับนี้ นอกจากนี้ยังทราบว่าcreatedฟังก์ชั่นไม่จำเป็นต้องเป็น async

สุดท้ายโปรดทราบว่าเป็นแนวทางปฏิบัติที่ดีในการเรียกใช้ฟังก์ชันยกเลิกการสมัครที่ส่งคืนโดย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();
  }
},

ในทางกลับกันหากคุณแค่ต้องการอ่านข้อมูลเอกสารเท่านั้น ONCEใน Vue.js hook ที่สร้างขึ้นคุณควรใช้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ฟังก์ชันต้องเป็นasyncเนื่องจาก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)
  },