【问题标题】:Firebase database data fetched multiple times in JavaScript在 JavaScript 中多次获取 Firebase 数据库数据
【发布时间】:2020-08-15 04:53:09
【问题描述】:

我在我的项目中使用 ReactJs。我正在制作一个聊天应用程序,我创建了 2 个组件,即 ChatRoom.jsInputMessage.js 用于消息目的。 ChatRoom.js 是从 Firebase 实时数据库加载的聊天,InputMessage.js 用于处理向用户显示的消息 InputMessage.js 工作正常,但问题出在 ChatRoom.js 每次获取数据时我都无法从数据库中检索数据,它会被多次获取

这是ChatRoom.js

的代码
import React, { useState, useEffect, useContext } from 'react';
import Header from './Header';
import { UserNameContext, RoomNameContext } from '../UserContext';
import background from './chatBackground.jpg';
import InputMessage from './InputMessage';
import { database } from '../firebase';

export default function ChatRoom() {
  const { userName, setUserName } = useContext(UserNameContext);
  const { roomName, setRoomName } = useContext(RoomNameContext);
  const messageContainer = {
    backgroundImage: `url(${background})`,
    backgroundRepeat: 'repeat-y !important',
    backgroundAttachment: 'fixed',
    backgroundPosition: 'center center',
    minHeight: '100vh',
    position: 'absolute',
    paddingTop: '100px',
    paddingBottom: '10vh',
    width: '100%'
  };
  const header = {
    position: 'fixed',
    zIndex: 99,
    width: '100%',
    height: 'auto'
  };

  const [details, setDetails] = useState([]);
  const [id, setId] = useState(0);
  useEffect(() => {
    //setDetails([]);
    var path = '';
    path = path.concat('Messages/', roomName, '/');
    var ref = database.ref(path);
    ref.on('value', (data) => {
      var items = data.val();
      var keys = Object.keys(items);
      var messageDB = Object.values(items);
      for (var i = 0; i < keys.length - 1; i++) {
        var k = keys[i];
        console.log(items[k].Message);
      }
    });
  });
  return (
    <div>
      <div style={header}>
        <Header />
      </div>

      <div>
        <div style={messageContainer}>
          {/* details.map(detail =>
          <div className='opponent msg'>{detail}</div>) */}

          {/* <div className='opponent msg'>
            <span className='by'>Deabrnab</span>
            <p>Hey! how are you please let me know how is it going</p>
            <span className='time'>11:20 am</span>
          </div>
          <div className='own msg'>
            <span className='by'>Deabrnab</span>
            <p className='text'>
              euiq gdbhqwdg gdbhqwdg gdbhqwdg gdbhqwdg gdbhqwdg gdbhqwdg
              gdbhqwdgysey
            </p>
            <span className='time'>11:20 am</span>
          </div> */}
        </div>
      </div>

      <InputMessage />
    </div>
  );
}

这是 InputMessage.js

的代码
import React, { useState, useEffect, useContext } from 'react';
import send from './sendMessage.png';
import { Input, Container, Row, Col } from 'reactstrap';
import Image from 'react-bootstrap/Image';
import { database } from '../firebase';
import { UserNameContext, RoomNameContext } from '../UserContext';

export default function InputMessage(prop) {
  var moment = require('moment');
  const { userName, setUserName } = useContext(UserNameContext);
  const { roomName, setRoomName } = useContext(RoomNameContext);

  const design = {
    width: '100%',
    background: 'black'
  };

  const [message, setMessage] = useState('');
  const date = moment().format('YYYYMMDD');
  const time = moment().format('h:mm a');
  const messageToDB = () => {
    const data = {
      Sender: userName,
      Message: message,
      Date: date,
      Time: time
    };
    var path = '';
    path = path.concat('Messages', '/', roomName);
    var ref = database.ref(path);
    ref.push(data);

    setMessage('');
  };
  return (
    <div style={design}>
      <Container>
        <Row>
          <div className='msg-textbox'>
            <Col>
              <Input
                className='input'
                type='text'
                placeholder='Type Message...'
                value={message}
                onChange={(e) => setMessage(e.target.value)}
              />
            </Col>
          </div>
          <div>
            <Col>
              <Image
                src={send}
                onClick={() => messageToDB()}
                className='send'
              />
            </Col>
          </div>
        </Row>
        <div></div>
      </Container>
    </div>
  );
}

这是我从 ChatRoom.js 中的数据库读取数据的部分,每当我在数组中存储消息时,它都会作为先前数据 + 当前获取的数据存储在数组中

var path = '';
path = path.concat('Messages/', roomName, '/');
var ref = database.ref(path);
ref.on('value', (data) => {
  setDetails([]);
  var items = data.val();
  var keys = Object.keys(items);
  var messageDB = Object.values(items);
  for (var i = 0; i < keys.length - 1; i++) {
    var k = keys[i];
    //console.log(items[k].Message);
    details.push(items[k].Message);
  }
  console.log(details);
});

我在数据库中的数据格式是

【问题讨论】:

    标签: javascript arrays reactjs firebase firebase-realtime-database


    【解决方案1】:

    使用集合代替数组和时间戳作为键解决

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-28
      • 2020-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多