简体   繁体   English

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

[英]Firebase: snapshot.val is not a function or its return value is not iterable

So I am creating a small application using Express, Firebase and ReactJS. 所以我正在使用Express,Firebase和ReactJS创建一个小应用程序。 I stubmled upon issue with Firebase snapshot.val 我发现了Firebase snapshot.val的问题

This part of code on express is serving my trips by ID and to get all. 快递代码的这一部分是通过ID为我的旅行服务并获得所有。 For all trips is working fine but when I try to go to the single trip it returns me this error 因为所有的旅行工作正常但是当我尝试去单程旅行时它会给我这个错误

if I destructure it as an array: 如果我将它解构为数组:

UnhandledPromiseRejectionWarning: TypeError: snapshot.val is not a function or its return value is not iterable UnhandledPromiseRejectionWarning:TypeError:snapshot.val不是函数或其返回值不可迭代

If I destructure it as a object: 如果我将它解构为一个对象:

TypeError: Cannot destructure property trip of 'undefined' or 'null'. TypeError:无法解析'undefined'或'null'的属性trip

and I am totally baffled and can't find the solution. 我完全感到困惑,无法找到解决方案。

Here is express part of the code: 这是代码的明确部分:

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();
};

I am fetching trips in the frontend with: 我正在前端进行旅行:

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

Controller for trips: 旅行控制器:

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;

And maping properties from object like this: 和对象的maping属性如下:

 {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>
      );
  })}

Here is image of single trip Single trip in firebase 这里是单程旅行的形象单人旅行在firebase

Any suggestions or directions? 有什么建议或指示吗? Thanks 谢谢

Might be an UnhandledPromiseRejectionWarning. 可能是UnhandledPromiseRejectionWarning。

Handle your snapshot with then/catch 用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
    })
};

Firebase generally recommends against storing data as arrays in the Realtime Database (though some exceptions exist): https://firebase.googleblog.com/2014/04/best-practices-arrays-in-firebase.html Firebase通常建议不要将数据作为数组存储在实时数据库中(尽管存在一些例外情况): https//firebase.googleblog.com/2014/04/best-practices-arrays-in-firebase.html

What I'm guessing is going on is that for some reason, your snapshot value is not being rendered as an array, but an object with numeric keys. 我猜测的是,由于某种原因,您的快照值不是呈现为数组,而是具有数字键的对象。 One reason for this might be if the keys in Firebase are not strictly sequential, as Firebase will only render your data as an array if keys of the data start with 0 and there are no gaps. 其中一个原因可能是Firebase中的密钥不是严格顺序的,因为如果数据的密钥以0开头且没有间隙,Firebase将只将数据呈现为数组。

Can you try this code to see if it works? 你能试试这段代码看它是否有效吗?

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;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM