Estoy creando una aplicación de chat en React Native con Firestore backend.
Mi estructura es así:
Channels -Channel { user1, user2, messages:[] (This is a subcollection not an array inside the document) }Quiero verificar si hay un canal que contiene los usuarios seleccionados.
Función de verificación:
const [chatRef, setChatRef] = useState() let channelRef = db.collection("Channels") channelRef.get().then((snapshot) => { snapshot.forEach((doc) => { let room = doc.data() if ( (room.user1.id === user.id || room.user2.id === user.id) && (room.user1.id === personToChat.id || room.user2.id === personToChat.id) ) { setChatRef(channelRef.doc(room.id).collection("Messages")) } else { channelRef.doc(user.id).set({ user1: user, user2: personToChat, }) setChatRef(channelRef.doc(user.id).collection("Messages")) } }) })efecto de uso:
useEffect(() => { const unsubscribe = chatRef.onSnapshot((querySnapshot) => { const messagesFirestore = querySnapshot .docChanges() .filter(({ type }) => type === "added") .map(({ doc }) => { const message = doc.data() return { ...message, createdAt: message.createdAt.toDate() } }) .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime()) appendMessages(messagesFirestore) }) return () => unsubscribe() }, [])¿Qué probé?
Todo esto conduce al mismo error, que es TypeError: undefined is not an object (evaluating 'chatRef.onSnapshot')
Lo resolví enviando chatRef como accesorio desde el componente principal. Y lo usó como una dependencia en el componente secundario.
Esta función es de la página de la lista de contactos. Maneja el evento de prensa en los contactos. Cuando se hace clic, navega a la sala de chat. Usé React.useRef para almacenar el chatRef y enviarlo como accesorio a la sala de chat.
if ( (room.user1.id === user.id || room.user2.id === user.id) && (room.user1.id === contact.id || room.user2.id === contact.id) ) { chatRef.current = channelRef.doc(room.id).collection("Messages") navigation.navigate("ChatRoom", { personToChat: contact, chatRef: chatRef.current, }) }Luego, en la pantalla de la sala de chat, lo usé como una dependencia y verifiqué si es nulo.
useEffect(() => { if (chatRef) { const unsubscribe = chatRef.onSnapshot((querySnapshot) => { const messagesFirestore = querySnapshot .docChanges() .filter(({ type }) => type === "added") .map(({ doc }) => { const message = doc.data() return { ...message, createdAt: message.createdAt.toDate() } }) .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime()) appendMessages(messagesFirestore) }) return () => unsubscribe() } }, [chatRef])Ocurre porque su estado chatRef no se inicializa cuando su useEffect se está ejecutando. Su useEffect solo se ejecuta una vez debido a la matriz vacía de dependencias.