使用Node.js的Firebase Cloud Firestore
你好。在本教程中,我们将解释Firebase Firestore在node.js应用程序中的实现。该应用程序将负责执行以下操作。
1.1.简介
Firebase是一个BaaS(Backend-as-a-Service),它有助于在数据库中存储实时数据。允许在所有设备上同步实时数据。
特点:
- 无服务器
- 高度安全
- 提供最小的设置
- 通过Angular Fire提供三方绑定
- 轻松访问数据、认证和更多
- 提供JSON存储,意味着数据和对象之间没有障碍
- 具有良好的存储潜力
就像其他的存储解决方案一样,Firebase也有一些优势,即
- 对查询和索引的支持有限
- 不支持聚合和map-reduce功能
1.1 设置Node.js
要在Windows上设置Node.js,你需要从这个链接中下载安装程序。点击你的平台的安装程序(也包括NPM包管理器),运行安装程序,开始Node.js设置向导。按照向导的步骤操作,完成后点击 "完成"。如果一切顺利,你可以导航到命令提示符来验证安装是否成功,如图1所示。
图1: 验证node和npm的安装
2.使用Node.js的Firebase Cloud Firestore
为了设置应用程序,我们将需要导航到我们的项目所在的路径。对于编程的东西,我正在使用Visual Studio Code作为我的首选IDE。你可以自由选择你喜欢的IDE。
2.1 设置Firebase项目
为了设置项目的实施,我们需要一个启用了实时数据库的Firebase项目。一旦项目被创建,就复制Firebase的配置,这将在.env 属性中使用。详情请参考第2.2.2节。你可以看一下这个链接,在google控制台快速创建一个firebase项目。
2.2 设置实现
让我们来写一下实际学习中需要的不同文件。
2.2.1 设置依赖项
导航到项目目录,运行npm init -y ,创建一个package.json 文件。这个文件持有与项目有关的元数据,用于管理项目的依赖关系、脚本、版本等。在该文件中添加以下代码,我们将指定所需的依赖性。
{
"name": "node-firebase",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"dotenv": "^10.0.0",
"express": "^4.17.1",
"firebase": "^8.0.1"
},
"devDependencies": {
"nodemon": "^2.0.15"
}
}
要下载依赖项,请导航到包含该文件的目录路径,并使用npm install 命令。如果一切顺利,依赖项将被加载到node_modules 文件夹中,你就可以进行下一步了。
2.2.2 创建一个环境文件
在环境文件中添加以下代码。该文件将负责将配置变量分散到整个应用程序中,以便进一步使用。
#express server configuration
PORT=3000
HOST=localhost
HOST_URL=http://localhost:3001
#firebase configuration
API_KEY=your_api_key
AUTH_DOMAIN=app_auth_domain
DATABASE_URL=app_realtime_database_url
PROJECT_ID=app_id
STORAGE_BUCKET=app_storage_bucket
MESSAGING_SENDER_ID=messaging_sender_id
APP_ID=app_id
2.2.3 创建配置文件
将下面的代码添加到配置文件中。该文件将负责从.env 文件中导入环境变量并执行初始化断言。这些断言有助于避免应用程序启动后的常见故障。
const dotenv = require("dotenv");
const assert = require("assert");
dotenv.config();
const {
PORT,
HOST,
HOST_URL,
API_KEY,
AUTH_DOMAIN,
DATABASE_URL,
PROJECT_ID,
STORAGE_BUCKET,
MESSAGING_SENDER_ID,
APP_ID
} = process.env;
// adding init assertions
assert(PORT, "Application port is required");
assert(HOST_URL, "Service endpoint is required");
assert(DATABASE_URL, "Firebase database endpoint is required");
assert(PROJECT_ID, "Firebase project id is required");
assert(APP_ID, "Firebase app id is required");
module.exports = {
port: PORT,
host: HOST,
url: HOST_URL,
firebaseConfig: {
apiKey: API_KEY,
authDomain: AUTH_DOMAIN,
databaseURL: DATABASE_URL,
projectId: PROJECT_ID,
storageBucket: STORAGE_BUCKET,
messagingSenderId: MESSAGING_SENDER_ID,
appId: APP_ID
}
};
2.2.4 创建数据库配置
在数据库配置文件中加入以下代码。该文件将负责初始化该应用程序所需的Firebase配置。
const firebase = require("firebase");
const config = require("./config");
const db = firebase.initializeApp(config.firebaseConfig);
module.exports = db;
2.2.5 创建一个模型类
在模型类中添加以下代码,该类将负责将数据映射到Firebase Firestore集合中/从该集合中获取数据。
class Employee {
constructor(id, fullName, age, contact, department) {
this.id = id; // represents the id generated by the firestore
this.fullName = fullName;
this.age = age;
this.contact = contact;
this.department = department;
}
}
module.exports = Employee;
2.2.6 创建一个控制器类
在控制器类中添加以下代码,它将负责从客户端获取数据并与Firebase Firestore集合进行交互。该类由不同的方法组成,用于保存一个新的雇员,更新/删除/通过id获取一个雇员,以及获取所有雇员。
const firebase = require("../db");
const Employee = require("../models/employee");
const fireStore = firebase.firestore();
// performing crud operations in the firebase firestore
// add
// get all
// get
// update
// delete
const addEmployee = async (req, res, next) => {
try {
console.log("Adding new employee");
const data = req.body;
await fireStore.collection("employees").doc().set(data);
res.status(201).json({ message: "Record saved successfully" });
} catch (error) {
res.status(400).json({ message: error.message });
}
};
const getAllEmployees = async (req, res, next) => {
try {
console.log("Getting all employees");
const employees = await fireStore.collection("employees");
const data = await employees.get();
const arr = [];
if (data.empty) {
res.status(200).json({ message: "No records found" });
} else {
let total = 0;
data.forEach((item) => {
const employee = new Employee(
item.id,
item.data().fullName,
item.data().age,
item.data().contact,
item.data().department
);
arr.push(employee);
total = total + 1;
});
res.status(200).json({
listing: arr,
count: total
});
}
} catch (error) {
res.status(400).json({ message: error.message });
}
};
const getEmployee = async (req, res, next) => {
try {
const id = req.params.id;
console.log("Getting employee= %s", id);
const employee = await fireStore.collection("employees").doc(id);
const data = await employee.get();
if (!data.exists) {
res.status(404).json({ message: "Record not found" });
} else {
res.status(200).json(data.data());
}
} catch (error) {
res.status(400).json({ message: error.message });
}
};
const updateEmployee = async (req, res, next) => {
try {
const id = req.params.id;
console.log("Updating employee= %s", id);
const data = req.body;
const employee = await fireStore.collection("employees").doc(id);
await employee.update(data);
res.status(204).json({ message: "Record updated successfully" });
} catch (error) {
res.status(400).json({ message: error.message });
}
};
const deleteEmployee = async (req, res, next) => {
try {
const id = req.params.id;
console.log("Deleting employee= %s", id);
await fireStore.collection("employees").doc(id).delete();
res.status(204).json({ message: "Record deleted successfully" });
} catch (error) {
res.status(400).json({ message: error.message });
}
};
// todo - add delete all employees
module.exports = {
addEmployee,
getAllEmployees,
getEmployee,
updateEmployee,
deleteEmployee
};
2.2.7 创建一个路由器类
在路由器类中添加以下代码,它将负责把来自客户端的请求映射到相应的控制器方法中。
const express = require("express");
const {
addEmployee,
getAllEmployees,
getEmployee,
updateEmployee,
deleteEmployee
} = require("../controllers/employeeController");
const router = express.Router();
// http://localhost:3000/api/employee
router.post("/employee", addEmployee);
// http://localhost:3000/api/employees
router.get("/employees", getAllEmployees);
// http://localhost:3000/api/employee/xxxx_employee_id
router.get("/employee/:id", getEmployee);
// http://localhost:3000/api/employee/xxxx_employee_id
router.put("/employee/:id", updateEmployee);
// http://localhost:3000/api/employee/xxxx_employee_id
router.delete("/employee/:id", deleteEmployee);
module.exports = {
routes: router
};
2.2.8 创建一个索引文件
添加以下代码到索引文件中,该文件将负责应用程序的启动并作为应用程序的欢迎点。
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const config = require("./config");
const employeeRoutes = require("./routes/employeeRoutes");
const app = express();
app.use(express.json());
app.use(cors());
app.use(bodyParser.json());
app.use("/api", employeeRoutes.routes);
app.listen(config.port, () => {
console.log("Service endpoint= %s", config.url);
});
3.运行应用程序
要运行该应用程序,请导航到项目目录,并输入以下命令,如图2所示。如果一切顺利,应用程序将在从.env 文件中读取的端口号上成功启动。在这种情况下,应用程序将在一个端口号上成功启动 -3001 。
Fig. 2: 启动应用程序
4.4.演示
你可以自由地使用postman或任何其他你选择的工具来向应用程序的端点发出HTTP请求。
// add an employee
// http post
http://localhost:3000/api/employee
// get all employees
// http get
http://localhost:3000/api/employees
// get an employee
// http get
http://localhost:3000/api/employee/xxxx_employee_id
// update an employee
// http put
http://localhost:3000/api/employee/xxxx_employee_id
// delete an employee
// http delete
http://localhost:3000/api/employee/xxxx_employee_id
这就是本教程的全部内容,我希望这篇文章能为你提供你想要的东西。祝你学习愉快,不要忘记分享!
5.总结
在本教程中,我们学习了如何在nodejs应用程序中集成Firebase。Firebase提供了一个实时数据库,提供了以JSON格式存储的数据,并提供了实现BaaS解决方案的快速方法。你可以从下载部分下载源代码和postman集合。

