代码之家  ›  专栏  ›  技术社区  ›  Martin Bories

Firebase函数-错误,但控制台中没有事件消息

  •  2
  • Martin Bories  · 技术社区  · 7 年前

    我在firebase上编写了一个函数,它从firebase存储中下载一个映像(base64),并将其作为响应发送给用户:

    const functions = require('firebase-functions');
    import os from 'os';
    import path from 'path';
    const storage = require('firebase-admin').storage().bucket();
    
    export default functions.https.onRequest((req, res) => {
        const name = req.query.name;
    
        let destination = path.join(os.tmpdir(), 'image-randomNumber');
        return storage.file('postPictures/' + name).download({
            destination
        }).then(() => {
            res.set({
                'Content-Type': 'image/jpeg'
            });
            return res.status(200).sendFile(destination);
        });
    });
    

    我的客户多次调用该函数 之后 彼此(串联)加载一系列图像以供显示,约20,平均大小为4KB。

    加载大约10张图片后(数量不同),所有其他图片都会失败。原因是我的函数没有正确响应,firebase控制台显示我的函数抛出了一个错误:

    enter image description here

    上图显示

    1. 对函数(称为“PostPictureView”)的请求成功
    2. 之后,对控制器的三个请求失败
    3. 最后,在对“UserLogin”函数执行一个新请求之后,也会失败。

    给客户端的响应是默认的“错误:无法处理请求”。等待几秒钟后,所有请求都会按预期方式再次得到处理。

    我的最佳猜测:

    • 这个项目是免费的,也许谷歌在限制什么?(我还没有达到任何极限)
    • google firebase控制台可以处理的消息是否有限制?
    • 功能应用程序中的tmpdir是否可以运行得很低?到目前为止,我从未删除过这些临时文件,但我希望谷歌会自动删除它们,或者以另一种方式警告我空间不足。

    是否有人知道接收错误消息的替代方法,或是否遇到过类似问题?(由于Firebase功能仍处于测试阶段,这也可能是谷歌的错误)

    顺便说一句:无法直接从客户端(android应用程序,react native)下载图像,因为我稍后将使用该功能检查访问权限。这个问题对我来说是可以复制的。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Doug Stevenson    7 年前

    在云函数中,/tmp目录是 backed by memory 。因此,您下载的每个文件都会有效地占用运行该功能的服务器实例上的内存。

    云函数可以重用服务器实例来重复调用同一函数。这意味着您的函数正在每次调用时下载另一个文件(到同一个实例)。由于文件的名称每次都不同,因此您正在/tmp中累积文件,每个文件都占用内存。

    在某个时候,当所有这些文件都位于/tmp中时,此服务器实例将耗尽内存。这很糟糕。

    最好的做法是 always clean up files after you're done with them 。更好的是,如果您可以将文件内容从云存储流式传输到客户端,您将使用更少的内存( and be billed even less for the memory-hours you use )。

        2
  •  0
  •   Martin Bories    7 年前

    经过进一步研究,我找到了解决方案:Firebase控制台似乎没有显示所有错误信息。

    有关函数的详细信息以及Firebase控制台中可能忽略的错误,请查看 website from google cloud functions

    enter image description here

    在那里,我看到了:内存(正如@DougStevensson所建议的)使用量从未超过80MB(限制为256MB),也从未关闭服务器。此外,我的应用程序遇到的免费层有DNS解析限制。

    这个 documentation 指向限制 DNS resolutions: 40,000 per 100 seconds 。就我而言,这一限制从未达到——据firebase统计,总共执行了8000个环岛——但似乎有一个 未记录的下限 对于免费层。升级我的账户(我开始了GCP提供的试用版,所以实际上什么都不付)并将项目链接到账单账户后,一切都很顺利。