Firebase:snapshot.val不是函数或其返回值不可迭代

时间:2019-03-20 09:31:12

标签: javascript node.js reactjs firebase express

因此,我正在使用Express,Firebase和ReactJS创建一个小型应用程序。 我对Firebase snapshot.val存有疑问。

express上的这部分代码通过ID来提供我的旅程并获得全部。对于所有行程,都可以正常工作,但是当我尝试进行单程行程时,会返回此错误

如果我将其分解为数组:

  

UnhandledPromiseRejectionWarning:TypeError:snapshot.val不是函数,或者其返回值不是   可迭代的

如果我将其分解为对象:

  

TypeError:无法解构'undefined'的属性trip或   'null'。

我很困惑,找不到解决方法。

这是代码的明确部分:

const firebase = require('firebase');

const reference = () => firebase.database().ref('/trips')

exports.getSingle = async (id) => {
  //const snapshot = await reference()
  //  .orderByChild('id')
  //  .equalTo(id)
  //  .limitToFirst(1)
  //  .once('value');

  // const [trip] = snapshot.val();
  //  return trip
const snapshot = await reference()
    .orderByChild('id')
    .equalTo(parseInt(id, 10))
    .limitToFirst(1)
    .once('value');
  let trip = [];
  snapshot.forEach(function (tripSnapshot) {
    tripStorage = tripSnapshot.val();
    console.log(tripStorage);
    trip.push(tripStorage);
  });
  console.log(trip);
  return trip;
};

exports.getAll = async () => {
  const snapshot = await reference().once('value');

  return snapshot.val();
};

我正在使用以下方式在前端获取行程:

 componentDidMount() {
    fetch("/api/trips/get/" + this.state.id)
      .then(res => res.json())
      .then(trip =>
        this.setState({
          trip
        }, () => console.log("Trips fetched...", trip))
      );
  }

旅行控制器:

const express = require('express');

const route = express.Router();
const tripUtil = require('../utils/tripUtil');

route.get('/getAll', async (req, res) => {
  const trips = await tripUtil.getAll();

  res.json(trips);
});

route.get('/get/:id', async (req, res) => {
  const { id } = req.params;
  const trip = await tripUtil.getSingle(id);

  if (trip) {
    res.json(trip);
  } else {
    res.status = 400;
    res.json({
      error: 'trip not found'
    });
  }
});

module.exports = route;

并映射对象的属性,如下所示:

 {this.state.trip.itinerary.days.map((day, i) => {
     return (
       <div key={i} className="trip-single-item__day">
          <div className="trip-single-item__day-header">
              <div className="trip-single-item__day-title">
                 {day.title}
              </div>
              <div className="trip-single-item__day-subtitle">
                 {day.subtitle}
              </div>
              <div className="trip-single-item__day-date">
                 {day.date}
              </div>
          </div>
          <div className="trip-single-item__day-body">
             <div className="trip-single-item__day-descritpion">
               {day.description}
             </div>
          </div>
      </div>
      );
  })}

这是单程Single trip in firebase

的图片

有什么建议或指示吗?谢谢

2 个答案:

答案 0 :(得分:0)

可能会成为未处理的PromiseRejection警告。

使用then / catch处理快照

exports.getSingle = async (id) => {
  await reference()
    .orderByChild('id')
    .equalTo(id)
    .limitToFirst(1)
    .once('value').then(snapshot => {

         const [trip] = snapshot.val();
         return trip

        //  console.log(post.id)  if required
    })
};

答案 1 :(得分:0)

Firebase通常建议不要将数据作为数组存储在实时数据库中(尽管存在一些例外):https://firebase.googleblog.com/2014/04/best-practices-arrays-in-firebase.html

我猜测是由于某种原因,您的快照值未呈现为数组,而是具有数字键的对象。原因之一可能是Firebase中的键不是严格顺序的,因为Firebase仅在数据键以0开头且没有空格的情况下才将数据呈现为数组。

您可以尝试使用此代码查看其是否有效吗?

exports.getSingle = async (id) => {
  const snapshot = await reference()
    .orderByChild('id')
    .equalTo(id)
    .limitToFirst(1)
    .once('value');

  const queryResult = snapshot.val()
  console.log(queryResult) // Make note of the object shape here. Make sure there are actually results.

  const trip = Object.values(queryResult)[0]
  return trip;
};