Nextjs函数在Vercel中的云无服务器功能中不起作用(以前称为zeit)

时间:2020-06-03 10:19:20

标签: node.js next.js serverless vercel

我正在尝试查询位于地图集(免费)上的MongoDB。我正在使用nextjs构建api。我尝试将其托管在vercel(以前称为zeit)中。该代码在本地工作正常。在部署到云(速度)时,它不起作用。

var MongoClient = require('mongodb').MongoClient;

// serverless function for proverbs of the day
export default async (req, res) => {
  return new Promise((resolve) => {
    let databaseString = process.env.DATABASE_URL;
    MongoClient.connect(
      databaseString,
      { useUnifiedTopology: true },
      async function (err, client) {
        if (err) {
          console.error(err);
          throw err;
        }

        var db = client.db('database_name');

        var start = new Date();
        start.setHours(0, 0, 0, 0);

        var end = new Date();
        end.setHours(23, 59, 59, 999);

        let result;
        try {
          // query 1 : doesn't works
          result = await db
            .collection('proverbs')
            .findOne({ createdAt: { $gt: start, $lt: end } });

          // query 2 : works
          // result = await db.collection('proverbs').findOne({'id': 11 })
        } catch (err) {
          console.error(err);
        } finally {
          client.close();
        }

        res.send(result);
        return resolve();
      },
    );
  });
};

我尝试了两个查询:查询1和查询2

在本地 查询1和2都有效

在Vercel Cloud服务器中 查询1不起作用 查询2幅作品

我想使查询1工作。我要去哪里错了?

2 个答案:

答案 0 :(得分:2)

此问题很可能是由于您的计算机与Vercel服务器之间的时区不同造成的。建议尽量使用UTC时间,以避免此类问题。

在您的情况下,仅使用setUTCHours而不是setHours应该会在生产中获得与localhost相同的结果。

答案 1 :(得分:0)

此问题很可能是由@Maxim Orlov回答的计算机与Vercel服务器之间的时区差异引起的。但是我不能接受他的回答,因为将 setHours 设置为 setUTCHours 不能解决问题。以下是我发现的内容:

解决方案

旧:这不起作用

result = await db
            .collection('proverbs')
            .findOne({ createdAt: { $gt: start, $lt: end } });

新功能:这项工作

result = await db
            .collection('proverbs')
            .findOne({ createdAt: { $gte: start, $lt: end } });

// also using setUTCHours instead of setHour is recommended, since UTC time is used.

说明

我有很多文档的时间戳格式如下 -2020-06-01 00:00:00.000 -2020-06-02 00:00:00.000 -等等。

情况1:为什么代码在本地给出结果?

  1. 本地计算机时区设置为+05:30
  2. 数据使用UTC的UTC时间(例如2020-06-03 00.00.00)存储在mongodb(地图集)中。
  3. 在本地计算机上的时间是2020-06-03 11:00:00(即+05:30)
  4. 让start = new Date.setHours(0,0,0,0)这是2020-06-02 18:30:00.000
  5. 让end = new Date.setHours(23,59,59,999),即2020-06-03 18:29:59.999
  6. 结果=等待数据库 .collection('谚语') .findOne({createdAt:{$ gt:start,$ lt:end}});
  7. createdAt(2020-06-03 00:00:00.000)>开始(2020-06-02 18:30:00.000)和createdAt(2020-06-03 00:00:00.000)<结束(2020-06 -03 18:29:59.000)。是(true和true),因此是true,因此返回结果。

情况2:为什么代码未在生产环境(vercel服务器)中给出结果?

  1. 自动售货机的时区设置为+00:00
  2. 数据使用UTC的UTC时间(例如2020-06-03 00.00.00)存储在mongodb(地图集)中。
  3. 在自动提款机中的时间为2020-06-03 05:30:00(即+00:00,即UTC)
  4. 让start = new Date.setHours(0,0,0,0)这是2020-06-03 00:00:00.000
  5. 让end = new Date.setHours(23,59,59,999),即2020-06-03 23:59:59.999
  6. 结果=等待数据库 .collection('谚语') .findOne({createdAt:{$ gt:start,$ lt:end}});
  7. createdAt(2020-06-03 00:00:00.000)>开始(2020-06-03 00:00:00.000)和createdAt(2020-06-03 00:00:00.000)<结束(2020-06) -03 23:59:59.000)。是(false和true),因此为false,不会返回任何结果。

注意:

  • 服务器时间设置为UTC
  • 因此setHour和setUTCHour将给予相同的时间
  • 为避免计算机与Vercel服务器之间的时区差异问题,请始终使用UTC