简体   繁体   English

请求后Firebase Cloud功能超时

[英]Post Request Firebase Cloud Functions Timing Out

I know that each HTTP function must end with end() or send(), so I'm thinking that might be related to my issue. 我知道每个HTTP函数都必须以end()或send()结尾,因此我认为这可能与我的问题有关。 I'm building a Shopify app that I want to host on Firebase. 我正在构建要在Firebase上托管的Shopify应用。 I've gotten it to authenticate and install, but when I try to capture the permanent access token via POST, Firebase times out. 我已经对其进行身份验证和安装,但是当我尝试通过POST捕获永久访问令牌时,Firebase超时。 This same code works fine with ngrok. 相同的代码可以与ngrok一起正常工作。 Entire route function below. 整个路由功能如下。

const dotenv = require('dotenv').config();
const functions = require('firebase-functions');
const express = require('express');

const app = express();
const crypto = require('crypto');
const cookie = require('cookie');
const nonce = require('nonce')();
const querystring = require('querystring');
const request = require('request-promise');

const apiKey = process.env.SHOPIFY_API_KEY;
const apiSecret = process.env.SHOPIFY_API_SECRET;
const scopes = 'read_products,read_customers';
const forwardingAddress = 'https://my-custom-app.firebaseapp.com/app';

app.get('/app/shopify/callback', (req, res) => {
  const { shop, hmac, code, state } = req.query;
  const stateCookie = cookie.parse(req.headers.cookie).__session;

  if (state !== stateCookie) {
    return res.status(403).send('Request origin cannot be verified');
  }

  if (shop && hmac && code) {
    // DONE: Validate request is from Shopify
    const map = Object.assign({}, req.query);
    delete map['signature'];
    delete map['hmac'];
    const message = querystring.stringify(map);

  const generatedHash = crypto
    .createHmac('sha256', apiSecret)
    .update(message)
    .digest('hex');

  if (generatedHash !== hmac) {
    return res.status(400).send('HMAC validation failed');
  }


  // Collect permanent access token
  const accessTokenRequestUrl = 'https://' + shop + '/admin/oauth/access_token';
  const accessTokenPayload = {
    client_id: apiKey,
    client_secret: apiSecret,
    code,
  };

  // Everything works up until here

  request.post(accessTokenRequestUrl, { json: accessTokenPayload })
    .then((accessTokenResponse) => {
        const accessToken = accessTokenResponse.access_token;

        // If below is uncommented, it will not show on browser, Firebase seems to timeout on the above request.post.
        //res.status(200).send("Got an access token, let's do something with it");

        // Use access token to make API call to 'shop' endpoint
        const shopRequestUrl = 'https://' + shop + '/admin/shop.json';
        const shopRequestHeaders = {
            'X-Shopify-Access-Token': accessToken,
        };

        request.get(shopRequestUrl, { headers: shopRequestHeaders })
            .then((shopResponse) => {
                res.end(shopResponse);
            })
            .catch((error) => {
                res.status(error.statusCode).send(error.error.error_description);
            });

    })
        .catch((error) => {
            res.status(error.statusCode).send(error.error.error_description);
        });
  } else {
res.status(400).send('Required parameters missing');
  }
});

exports.shopifyValidate = functions.https.onRequest(app);

You're calling response.end() incorrectly: 您正在错误地调用response.end()

    request.get(shopRequestUrl, { headers: shopRequestHeaders })
        .then((shopResponse) => {
            res.end(shopResponse);
        })

As you can see from the linked documentation, end() doesn't take a parameter. 从链接的文档中可以看到,end()不带参数。 It just ends the response. 它只是结束响应。 You probably want to be calling send() instead if you have data to send. 如果您有要发送的数据,则可能要调用send()。

If you're unsure how your function is executing, also use console.log() to log messages to figure out exactly what it's doing. 如果不确定函数的执行方式,还可以使用console.log()记录消息以准确了解其功能。 It's rarely a good idea to just hope that a bunch of code is just working - you should verify that it's working the way you expect. 只是希望一堆代码能够正常工作,这不是一个好主意-您应该验证它是否按预期的方式工作。

Solved. 解决了。 Turns out you need a paid plan (Blaze, pay as you go) to access external APIs. 事实证明,您需要付费计划(Blaze,即付即用)才能访问外部API。 I upgraded and that solved the issue. 我升级后,问题解决了。

What is the request module that you are using for the request.post() Please see : https://www.npmjs.com/package/request#promises--asyncawait 您用于request.post()的请求模块是什么?请参阅: https : //www.npmjs.com/package/request#promises--asyncawait

I hope you are using the https://github.com/request/request-promise module instead of request. 我希望您使用的是https://github.com/request/request-promise模块,而不是request。

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

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