如何从需要参数的文档中的 firestore 集合中获取数据?

问题描述 投票:0回答:1

我正在尝试创建和管理聊天,管理员可以在其中查看所有用户消息,然后回复它们我已经能够将文档添加到此集合,但我无法显示消息,以便管理员可以阅读它们这一页。到目前为止,我已经尝试了两种方法,其中一种是我之前用于以下类似请求的方法。

import { projectFirestore } from "../Firebase/Config";
import { ref, watchEffect } from "vue"

const getChatMess = (id) => {
    const ChatMess = ref([])
    const error = ref(null)
    let lastDoc = null; 

    const load = async () => {
        try {
            let query = projectFirestore.collection('ChatMess').doc(id).collection('Messages').orderBy('createdAt')
            if (lastDoc) {
                query = query.startAfter(lastDoc)
            }

            const res = await query.get()

            if (!res.empty) {
                lastDoc = res.docs[res.docs.length - 1]

                // Add new results to exsiting ones

                ChatMess.value = [...ChatMess.value, ...res.docs.map(doc => {
                  //  console.log(doc.data())
                    return {...doc.data(), id: doc.id}
                })]
            }
        }
        catch (err){
            error.value = err.message
           // console.log(error.value)
        }
    }

    return { ChatMess, error, load }
}

export default getChatMess

当我 concole.log(ChatMess) 阅读 firebase 文档后,我可以在控制台日志中看到一个数组,但它不会显示这些值,因为它们位于数组中。

import { projectFirestore } from "../Firebase/Config";
import { ref, watchEffect } from "vue"

const getChatMess = (id) => {
    const ChatMess = ref(null)
    const error = ref(null)


            let collectionRef = projectFirestore.collection('Subscribed').doc(id).collection('messages').orderBy('createdAt')
            const unsub = collectionRef.onSnapshot(snap => {
                console.log(snap)
                let results = []
                snap.docs.forEach(doc => {
                  // must wait for the server to create the timestamp & send it back
                  // we don't want to edit data until it has done this
                  doc.data().createdAt && results.push({...doc.data(), id: doc.id})
                });
                
                // update values
                ChatMess.value = results
                error.value = null 
                console.log(ChatMess)
              }, err => {
              
                console.log(err.message)
                ChatMess.value = null
                error.value = 'could not fetch the data'
              })
            
              watchEffect((onInvalidate) => {
                // unsub from prev collection when watcher is stopped (component unmounted)
                onInvalidate(() => unsub());
              });

    return { ChatMess, error }
}

export default getChatMess

这两个文件都在自己的 Javascript 文件中,然后我将 getChatMess 导入到我希望显示消息的页面,如下所示。

<script>
import { projectFirestore } from '../Firebase/Config'
import getChatMess from "../Composables/getChatMess";
import { ref } from 'vue'
import { timestamp } from '../Firebase/Config'
import { useRoute } from 'vue-router'
export default {


  setup(){
    const route = useRoute()
    console.log(route)
    console.log(route.params)
    const { Chatmess, error } = getChatMess(route.params.id);
 
    const message = ref('')
    const Activate = ref(false)
    const handleSubmit = async () => {  
    const NewChatmess = {
        message: message.value,
        createdAt: timestamp(),
    }
    const res = await projectFirestore.collection('Subscribed').doc(route.params.id).collection('messages').add(NewChatmess)
  }
  return { handleSubmit, Activate, message, Chatmess }
}
}
    </script>

    <template>
      <div class="chat-window">
        <div v-for =" doc in Chatmess" :key="doc.id">
            <span class="created-at">{{ doc.createdAt }}</span>
            <span class="name">{{ doc.name }}</span>
            <span class="message">{{ doc.message }}</span>
          </div>
          <form @submit.prevent="handleSubmit">
      <textarea
        placeholder="Type a message and hit enter to send..." 
        v-model="message"
      ></textarea>
      <button @click="Loading = true" class="bg-neutral-800 hover:bg-neutral-900 active:bg-neutral-800 text-red-700 hover:text-neutral-400 hover:scale-105 text-xl w-64 p-4 rounded-xl shadow cursor-pointer inline-block m-10 transition ease-in-out duration-300 drop-shadow-2xl"
      >{{ Loading ? "Sending..." : "Send" }}</button>
      <div v-if="error" class="error">{{ error }} blah</div>
    </form>
        </div>

    </template>

我不确定为什么第一个Javascript文件代码不起作用,我做了完全相同的事情来获取数据,唯一的区别是,而不是doc(id)具有route.params.id的id参数我用过

import { projectFirestore } from "../Firebase/Config";
import { ref } from "vue"
import { firebaseAuth } from "../Firebase/firebase";

const getChat = () => {
    const Chat = ref([])
    const error = ref(null)
    let lastDoc = null; 

    const load = async () => {
        try {
            let query = projectFirestore.collection('Subscribed').doc(firebaseAuth.currentUser.uid).collection('messages').orderBy('createdAt')
            if (lastDoc) {
                query = query.startAfter(lastDoc)
            }

            const res = await query.get()

            if (!res.empty) {
                lastDoc = res.docs[res.docs.length - 1]

                // Add new results to exsiting ones

                Chat.value = [...Chat.value, ...res.docs.map(doc => {
                  //  console.log(doc.data())
                    return {...doc.data(), id: doc.id}
                })]
            }
        }
        catch (err){
            error.value = err.message
           // console.log(error.value)
        }
    }

    return { Chat, error, load }
}

export default getChat

这在过去工作得很好,我首先假设route.params.id无法正常工作,但我能够console.log它并删除.doc(id)之后的所有内容,并且我能够看到route.params工作正常。有谁知道该怎么做吗?

javascript firebase google-cloud-firestore
1个回答
0
投票

我通常使用

onSnapshot
方法来监听实时更新。

import { projectFirestore } from "../Firebase/Config";
import { ref, watchEffect } from "vue";

   const getChatMess = (id) => {
    const ChatMess = ref([]);
    const error = ref(null);

let collectionRef = projectFirestore.collection('Subscribed').doc(id).collection('messages').orderBy('createdAt');

const unsub = collectionRef.onSnapshot(snap => {
let results = [];
  snap.docs.forEach(doc => {
    doc.data().createdAt && results.push({ ...doc.data(), id: doc.id });
  });
  ChatMess.value = results;
  error.value = null;
}, err => {
  console.log(err.message);
  ChatMess.value = null;
  error.value = 'could not fetch the data';
});

watchEffect((onInvalidate) => {
onInvalidate(() => unsub());
});

return { ChatMess, error };
  };

  export default getChatMess;

还要修复脚本中的拼写错误,其中

Chatmess
应为
ChatMess
,并确保
Chatmess
变量正确绑定到组件模板。

<script>
import { projectFirestore, timestamp } from '../Firebase/Config';
import getChatMess from "../Composables/getChatMess";
import { ref } from 'vue';
import { useRoute } from 'vue-router';

export default {
  setup() {
    const route = useRoute();
    const { ChatMess, error } = getChatMess(route.params.id);

    const message = ref('');
    const handleSubmit = async () => {
      const NewChatmess = {
        message: message.value,
        createdAt: timestamp(),
      };
      await projectFirestore.collection('Subscribed').doc(route.params.id).collection('messages').add(NewChatmess);
  message.value = ''; // Clear the input after sending the message
};

return { handleSubmit, message, ChatMess, error };
  }
};
</script>
© www.soinside.com 2019 - 2024. All rights reserved.