【问题标题】:Builds a chat app in React, using axios and firestore使用 axios 和 firestore 在 React 中构建一个聊天应用程序
【发布时间】:2021-06-13 17:24:46
【问题描述】:

如果有人愿意帮助我,我会很高兴

我有一个问题,我不能使用服务器端的函数,我用axios调用函数,并在react hooks中执行。

我实际上建立了聊天,这就是我使用 react hook 的原因,因为我希望消息一直更新。

我也使用 Firestore。我在那里保存消息,并通过服务器端函数接收它们。

这是聊天的一个组成部分 - 它给我带来了问题,我不明白为什么。

服务器端功能运行良好,我在邮递员中对其进行了测试,并且它们运行良好。问题是我不能在函数组件中运行它们。我不知道我做错了什么。

我在这里得到的错误是在chat.users.length> 0? 行中,当我进行这个比较时,我得到chat.users 是未定义的,但我不明白为什么,因为我首先使用服务器端函数对其进行了初始化,哪个提供必要的信息

我很困惑,我是这个网站的新手,我想弄清楚为什么它整整两天都没有工作

我想我可能对语法感到困惑,例如在聊天组件内部使用了不必要的调度

我收到了这个错误:

enter image description here

聊天组件

import React, { useEffect, useState } from 'react';
import './style.css';
import { useDispatch, useSelector } from 'react-redux';
import { getRealtimeUsers, updateMessage, getRealtimeConversations } from '../../redux/actions/chatActions';
import { Fragment } from 'react';


const User = (props) => {


  const { chat, onClick } = props;

  return (
    <div onClick={() => onClick(chat)} className="displayName">
      <div className="displayPic">
        <img src="https://i.pinimg.com/originals/be/ac/96/beac96b8e13d2198fd4bb1d5ef56cdcf.jpg" alt="" />
      </div>
      <div style={{ display: 'flex', flex: 1, justifyContent: 'space-between', margin: '0 10px' }}>
        <span style={{ fontWeight: 500 }}>{chat.firstName} {chat.lastName}</span>
        <span className={chat.isOnline ? `onlineStatus` : `onlineStatus off`}></span>
      </div>
    </div>
  );
}

const HomePage = (props) => {

  const dispatch = useDispatch();
  const user = useSelector(state => state.user.credentials);
  const chat = useSelector(state => state.chat);
  const [chatStarted, setChatStarted] = useState(false);
  const [chatUser, setChatUser] = useState('');
  const [message, setMessage] = useState('');
  const [userUid, setUserUid] = useState(null);
  let unsubscribe;


  useEffect(() => {

    //unsubscribe = dispatch(getRealtimeUsers(user.handle))
    dispatch(getRealtimeUsers());

  }, []);

  //console.log(user);

  //componentWillUnmount
  useEffect(() => {
    return () => {
      //cleanup
      //unsubscribe.then(f => f()).catch(error => console.log(error));
      unsubscribe.then(f => f()).catch(error => console.log(error));

    }
  }, []);


  //function
  const initChat = (chat) => {

    setChatStarted(true)
    setChatUser(`${chat.firstName} ${chat.lastName}`)
    setUserUid(chat.handle);

    console.log(chat);

    dispatch(getRealtimeConversations({ uid_1: user.handle, uid_2: chat.handle }));

  }

  const submitMessage = (e) => {

    const msgObj = {
      user_uid_1: user.handle,
      user_uid_2: userUid,
      message
    }


    if (message !== "") {
      dispatch(updateMessage(msgObj))
        .then(() => {
          setMessage('')
        });
    }

    //console.log(msgObj);

  }


  return (
    <Fragment>
      <section className="container">

        <div className="listOfUsers">
          {console.log(chat)}
          {
            //chat.users != undefined 
            chat.users.length > 0 ?
                chat.users.map(user => {
                  return (
                    <User
                      onClick={initChat}
                      key={user.handle}
                      user={user}
                    />
                  );
                })
                : null
          }



        </div>

        <div className="chatArea">

          <div className="chatHeader">
            {
              chatStarted ? chatUser : ''
            }
          </div>
          <div className="messageSections">
            {
              chatStarted ?
                chat.conversations.map(con =>
                  <div style={{ textAlign: con.user_uid_1 == user.handle ? 'right' : 'left' }}>
                    <p className="messageStyle" >{con.message}</p>
                  </div>)
                : null
            }


          </div>
          {
            chatStarted ?
              <div className="chatControls">
                <textarea
                  value={message}
                  onChange={(e) => setMessage(e.target.value)}
                  placeholder="Write Message"
                />
                <button onClick={submitMessage}>Send</button>
              </div> : null
          }

        </div>
      </section>
    </Fragment>
  );
}

export default HomePage;

这是 axios:

app.get('/realtimeUsers', FBAuth, getRealtimeUsers );
app.post('/updateMessage', FBAuth, updateMessage);
app.get('/realtimeConversations', FBAuth, getRealtimeConversations);

这是服务器端功能 - 它们 100% 工作 - 我检查了很多次,它们都工作了。:

const { db } = require('../util/admin');

exports.getRealtimeUsers = (req, res) => {

    db.collection("users")
        .onSnapshot((querySnapshot) => {
            const users = [];
            querySnapshot.forEach(function (doc) {
                if (doc.data().handle != req.user.handle) {
                    users.push(doc.data());
                }
            });
            return res.json(users);
        });
}

exports.updateMessage = (req, res) => {
    db.collection('conversations')
        .add({
            ...req.body,
            isView: false,
            createdAt: new Date()
        })
        .then(() => {
            return res.json({ message: "Conversations added successfully" });
        })
        .catch((err) => {
            console.error(err);
            return res.status(500).json({ error: err.code });
        });
}

exports.getRealtimeConversations = (req, res) => {

    console.log(JSON.stringify("testing"));
    console.log(JSON.stringify(req.query));
    console.log(JSON.parse(req.query.user));
    console.log(JSON.parse(req.query.user).uid_1);
    console.log(JSON.parse(req.query.user).uid_2);

    db.collection('conversations')
        .where('user_uid_1', 'in', [JSON.parse(req.query.user).uid_1, JSON.parse(req.query.user).uid_2])
        .orderBy('createdAt', 'asc')
        .onSnapshot((querySnapshot) => {

            const conversations = [];

            querySnapshot.forEach(doc => {
                console.log(JSON.stringify(doc));
                if (
                    (doc.data().user_uid_1 == JSON.parse(req.query.user).uid_1 && doc.data().user_uid_2 == JSON.parse(req.query.user).uid_2)
                    ||
                    (doc.data().user_uid_1 == JSON.parse(req.query.user).uid_2 && doc.data().user_uid_2 == JSON.parse(req.query.user).uid_1)
                ) {
                    conversations.push(doc.data())
                }

            });
            console.log(conversations);
            return res.json(conversations);
        })
        
        //return res.json([]);
}

这是在客户端使用的操作,这里我调用 axios:

import { userConstants } from "../types";
import axios from 'axios';

export const getRealtimeUsers = () => (dispatch) => {
    dispatch({ type: `${userConstants.GET_REALTIME_USERS}_REQUEST` });
    axios
        .get('/realtimeUsers')
        .then((res) => {
            console.log(res);
            dispatch({
                type: `${userConstants.GET_REALTIME_USERS}_SUCCESS`,
                payload: res.data
            });
        })
        .catch((err) => console.log(err))
}

export const updateMessage = (msgObj) => (dispatch) => {

    axios.post('/updateMessage', msgObj)
        .then(() => { })
        .catch((err) => console.log(err));
}

export const getRealtimeConversations = (user) => (dispatch) => {

    //user = { uid_1: "from visualcode", uid_2: "userUid" };
    console.log(JSON.stringify(user));
    axios.get('/realtimeConversations', 
    {
        params: {
            user: JSON.stringify(user)
            //uid_1:JSON.stringify("user.handle"),
            //uid_2:JSON.stringify("userUid")
        }
      }
    )
        .then((res) => {
            dispatch({
                type: userConstants.GET_REALTIME_MESSAGES,
                payload: res.data
            });
        })
        .catch((err) => console.log(err))

}

【问题讨论】:

    标签: node.js reactjs firebase google-cloud-firestore axios


    【解决方案1】:

    我无法理解您的整个代码流程,即在调用 initChat 之前如何填充 chat.users。

    但是,对于您的问题,您应该始终在遍历数组时检查未定义的值。

    <div className="listOfUsers">
              {console.log(chat)}
              {
                //chat.users != undefined 
                chat && chat.users && chat.users.length > 0 &&
                    chat.users.map(user => {
                      return (
                        <User
                          onClick={initChat}
                          key={user.handle}
                          user={user}
                        />
                      );
                    })
              }
            </div>
    

    【讨论】:

    • 感谢您的帮助,它没有解决我的问题,我收到此错误:prnt.sc/10n9jmh
    猜你喜欢
    • 1970-01-01
    • 2019-12-20
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    • 2016-12-06
    相关资源
    最近更新 更多