目录
- 简介
- 关于
- 安装和更新
- 用法
- 运行测试
- 环境变量
- Bash 补全
- 兼容性问题
- 在 Alpine Linux 上安装 nvm
- 卸载/删除
- Docker 用于开发环境
- 问题
- macOS 故障排除
- WSL 故障排除
- 维护者
- 项目支持
- 企业支持
- 执照
- 版权声明
简介
nvm
让您快速...
你知道他们怎么说。在一个充满无服务器的世界里,部署……无服务器。所以,我当然会尽自己的一份力。我当时正在做一个只需要静态页面的小项目,最大的挑战是如何收集用户的反馈(通过静态表单)。我最初的想法是构建一个小型 API,从表单中获取数据并将其存储在数据库中。但是网站的流量并不大,所以我认为没有必要为了每周几个请求而全天候提供 API。
我遇到的最流行的解决方案当然是无服务器。使用AWS Lambda或Netlify有很多方法。但是我的静态页面已经部署在Firebase Hosting上,所以我不得不尝试一下Google Cloud Functions for Firebase。
@adnanrahic很好地解释了无服务器的优缺点(与容器的比较)。
对于这个特定的项目来说,无服务器架构是完美的选择:易于编写、部署和维护。无需关心任何基础设施,我可以用自己喜欢的语言和包来编写,甚至可以在本地进行测试。非常方便。
无需设置或扩展服务器,我们只需编写函数并将其部署到 Firebase。它们仅在请求被调用时才会触发。
目前,Google Cloud Functions 可以使用Node.js(v6 或 v8)、Python(测试版)或Go(测试版)编写。我将继续介绍 Node.js 以及一些其他资源,例如Express和CORS。
在开始之前,请确保您已正确配置Node.js和npm,因为我们将在 Node.js 中编写函数。
有些人会推荐你使用nvm来安装和管理 Node.js 版本。
但是如果您也可以使用图形说明。
注册或登录Firebase 控制台并创建一个新项目。其实没什么区别,但我的名为dev-form-entries
。
现在,在本地设置您的项目。
首先,全局安装Firebase CLI。
npm install -g firebase-tools
现在为您的项目创建一个本地文件夹。
mkdir dev-form-entries
cd dev-form-entries
在项目文件夹中,登录 Firebase。
$ firebase login
Success! Logged in as me@tld.com
让我们初始化我们的第一个 Firebase 项目(您可以firebase init
稍后实际运行并添加功能)。
firebase init functions
为该目录选择一个默认的 Firebase 项目: dev-form-entries
你想用什么语言? JavaScript
我们现在用 Javascript。Typescript 也可以。
你想用 ESLint 来捕捉潜在的 bug 吗? No
不错的选择,但目前还不需要。
你想现在用 npm 安装依赖项吗? Yes
运行它来npm install
安装。firebase-functions
firebase-admin
好的,让我们看看我们得到了什么
firebase.json
用于配置Firebase Hosting,.firebaserc
用于配置多个项目,functions/index.js
是 Firebase 提供的样板。我们稍后会继续讨论。这里不需要配置太多,因为它将通过编程方式初始化。但我还是想趁还没太迟之前提一下。
正如我之前提到的,我希望将所有数据存储在数据库中。Firebase 有两个很棒的开箱即用数据库可供使用:实时数据库 (Realtime Database)和Cloud Firestore。它们都具有高度的可扩展性和灵活性(我稍后会讲到),但我选择使用实时数据库,因为它不需要任何预配置,我们只需在代码中引用它即可。
@aurelkurtula可能会让您一睹实时数据库的伟大之处。
让我们从 Firebase 的 hello world 开始。编辑functions/index.js
并保留其示例。
const functions = require('firebase-functions');
// Create and Deploy Your First Cloud Functions
// https://firebase.google.com/docs/functions/write-firebase-functions
exports.helloWorld = functions.https.onRequest((request, response) => {
response.send("Hello from Firebase!");
});
此功能将创建一个路由,并对每个请求/helloWorld
做出响应。Hello from Firebase!
现在,您的第一次部署。
firebase deploy --only functions
或者您可以直接运行,firebase deploy
因为此时项目只包含一个功能。
=== Deploying to 'dev-form-entries'...
i deploying functions
i functions: ensuring necessary APIs are enabled...
✔ functions: all necessary APIs are enabled
i functions: preparing functions directory for uploading...
i functions: packaged functions (42.53 KB) for uploading
✔ functions: functions folder uploaded successfully
i functions: updating Node.js 6 function helloWorld(us-central1)...
✔ functions[helloWorld(us-central1)]: Successful update operation.
✔ Deploy complete!
现在您的部署已完成,您可以转到Firebase 控制台并找到您的功能。
这是一个简洁的仪表盘。您可以检查运行状况并阅读函数日志。您可以重定向到 Google Cloud Platform 查看完整的详细信息和配额。
我将使用Postman来测试这些函数。Postman 是一款测试 API 的好工具,今天我只会讲解一些非常基础的部分,不过你也可以查看@harshitrathod的新手指南,或者通过@jlozovei的《Going beyond with Postman》来深入了解。
如仪表板所示,我的函数路由是https://us-central1-dev-form-entries.cloudfunctions.net/helloWorld
。我将把它粘贴到 Postman 中并发出GET
请求。
好了,现在你知道在哪里编写、部署和测试代码了。让我们尝试做一些实际的事情。
作为我们伟大目标的小助手,我们将使用Express(用于中间件和更好的路由编写)和CORS(用于启用所有 CORS 请求,如果您不熟悉它,请查看一些 @effingkay 的 CORS 概念)。
首先,你需要安装它们,所以进入你的终端
npm install --save express cors
并将它们添加到文件顶部index.js
。
const express = require('express');
const cors = require('cors');
紧接着,创建一个 Express 实例并编写接受所有 CORS 请求的中间件。
const app = express();
app.use(cors());
您将使用该app
实例编写路由,并将其导出为 Google Cloud Function,就像之前操作的那样helloWorld
。因此,请在导出后立即编写新的路由helloWorld
。
exports.entries = functions.https.onRequest(app);
这将创建一个/entries
函数。我们为该实例编写的所有路由都app
将在该entries
函数中可用。
为了使用实时数据库,您需要导入并初始化它。
const admin = require('firebase-admin');
admin.initializeApp();
我通常会从GET
路由开始,但我们需要先获取条目才能获取它们。所以你需要编写POST
路由来将数据推送到数据库。
ExpressPOST /
路线的一个基本示例是
app.post('/', (request, response) {
// send stuff...
});
实时数据库的有趣之处在于它非常灵活,因此您无需事先设计整个结构。由于它将数据存储为一棵 JSON 树,因此我们可以推送一个 JSON 结构,这已经足够了。当然,如果所有字段都推送到数据库,则需要进行验证,不过这个问题留待下次再讨论。
因此,存储在数据库中的条目将是请求本身的主体。
const entry = request.body;
数据推送到数据库的方式是
return admin.database().ref('/entries').push(entry);
/entries
是数据库引用的路径。
该push
函数返回一个 Promise,我们将用它来验证并发送响应。如果已完成,我们将返回推送的条目和200
状态码。否则,捕获错误并将其作为 发送Internal Server Error
。
return admin.database().ref('/entries').push(entry)
.then(() => {
return response.status(200).send(entry)
}).catch(error => {
console.error(error);
return response.status(500).send('Oh no! Error: ' + error);
});
从本质上来说,就是这样!
'use strict'; | |
const express = require('express'); | |
const cors = require('cors'); | |
// Firebase init | |
const functions = require('firebase-functions'); | |
const admin = require('firebase-admin'); | |
admin.initializeApp(); | |
// Express and CORS middleware init | |
const app = express(); | |
app.use(cors()); | |
// POST / method | |
app.post("/", (request, response) => { | |
const entry = request.body; | |
return admin.database().ref('/entries').push(entry) | |
.then(() => { | |
return response.status(200).send(entry) | |
}).catch(error => { | |
console.error(error); | |
return response.status(500).send('Oh no! Error: ' + error); | |
}); | |
}); | |
exports.entries = functions.https.onRequest(app); |
快速部署后,我将其放入 Postman 中并向发出 POST 请求/entries
。
name:John Doe
subject:dev.to
message:Hello dev.to!
如果您浏览到Firebase 控制台,在数据库下您将能够看到所有条目。
为了获取数据库的所有数据,我们将使用
admin.database(...).ref(...).on(...)
它将通过回调返回所有存在的条目。
这实际上是一个监听器函数,因此每次数据库中出现新条目时,它都会被调用(如果您有一个静态页面来监视这些条目,那就太酷了)。
这次没有承诺,只是一个返回值的回调snapshot
。
app.get("/", (request, response) => {
return admin.database().ref('/entries').on("value", snapshot => {
return response.status(200).send(snapshot.val());
}, error => {
console.error(error);
return response.status(500).send('Oh no! Error: ' + error);
});
});
在 Postman 中调用它我得到了包含所有条目的 JSON。
{
"-LZadZujD5Qb1MrQvAd_": {
"message": "Hello, dev.to!!!",
"name": "John Doe",
"subject": "dev.to"
},
"-LZaeMZYJjQ2weey6k7H": {
"message": "Hello dev.to!",
"name": "Jess Doe",
"subject": "dev.to"
},
"-LZaeQc8DAOn0A6B1Gzc": {
"message": "Hello dev.to!",
"name": "Jane Doe",
"subject": "dev.to"
}
}
如果您部署它们,您可以从仪表板监控其功能。
但请注意,如果您为 Express 应用程序的同一个实例编写配额,则将无法看到每条路线的配额。
将所有小改动都部署到 Firebase 上进行测试会非常麻烦。Firebase 允许您在本地测试所有这些功能。
firebase serve --only functions
这将在本地提供您的功能,只需使用终端中生成的链接即可。
✔ functions: entries: http://localhost:5000/dev-form-entries/us-central1/entries
✔ functions: helloWorld: http://localhost:5000/dev-form-entries/us-central1/helloWorld
这真的不算什么。这只是无服务器 API、Google Cloud Functions 和 Firebase 实时数据库的精彩之处的冰山一角。还有其他数据处理方式(例如删除或更新数据)。此外,你还需要在这些方式之上添加大量的验证和安全层。
以上就是我想分享的基础知识。我其实正在考虑写一个关于 Firebase 上的无服务器 API 的系列文章,同时我自己也会记录一下这个话题。请告诉我你是如何使用 Firebase 的,以及你用它的所有功能做了哪些有趣的事情。
爱!
文章来源:https://dev.to/bogdaaamn/getting-started-with-google-cloud-functions-on-firebase-3g29