我正在尝试创建和管理聊天,管理员可以在其中查看所有用户消息,然后回复它们我已经能够将文档添加到此集合,但我无法显示消息,以便管理员可以阅读它们这一页。到目前为止,我已经尝试了两种方法,其中一种是我之前用于以下类似请求的方法。
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工作正常。有谁知道该怎么做吗?
我通常使用
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>