- App Inventor 2 云数据库配置教程 - Firebase/CloudDB/自建后台
App Inventor 2 云数据库配置教程 - Firebase/CloudDB/自建后台
在App Inventor 2中,如果你的应用需要在多台设备之间共享数据,或者需要将数据持久化存储在云端,就需要使用云数据库组件。本文将全面介绍App Inventor 2提供的云存储方案,并给出详细的配置步骤和实践代码。
一、云存储方案对比
App Inventor 2内置了多种云端数据存储组件,每种方案各有适用场景:
| 特性 | CloudDB | FirebaseDB | TinyWebDB(自建后台) | Google Spreadsheet |
|---|---|---|---|---|
| 底层技术 | Redis服务器 | Google Firebase Realtime DB | 自定义Web服务API | Google Sheets API |
| 默认服务器 | MIT提供默认服务器 | 需自行配置Firebase项目 | 需自行搭建 | 需配置Google账户 |
| 实时同步 | ✅ 支持DataChanged事件 | ✅ 实时数据监听 | ❌ 需手动轮询 | ❌ 需手动轮询 |
| 数据共享 | ✅ 多用户共享 | ✅ 多用户共享 | ✅ 多用户共享 | ✅ 多用户共享 |
| 离线支持 | ❌ 需联网 | ✅ 本地缓存+同步 | ❌ 需联网 | ❌ 需联网 |
| 列表操作 | ✅ 原子追加/移除 | ✅ 支持 | ❌ 需自行实现 | ✅ 读写行列 |
| 安全规则 | Token认证 | Firebase Rules | 自行实现 | Google权限管理 |
| 适用场景 | 通用云端存储、实时协作 | 实时聊天、排行榜 | 完全自定义业务逻辑 | 数据报表、表单收集 |
| 难度 | ⭐ 简单 | ⭐⭐ 中等 | ⭐⭐⭐ 较高 | ⭐⭐ 中等 |
| 费用 | MIT免费(有限额) | Firebase免费额度 | 服务器自费 | Google免费额度 |
二、CloudDB —— MIT官方云数据库
2.1 简介
CloudDB是App Inventor 2内置的非可视化组件,基于Redis服务器实现。它允许应用用户之间共享数据。默认情况下,数据存储在MIT维护的服务器上,你也可以搭建自己的Redis服务器。
核心特点:
- 开箱即用,默认配置即可直接使用
- 支持实时数据变更通知(DataChanged事件)
- 原子性列表操作,多设备并发安全
- 支持自建Redis服务器
2.2 配置步骤(使用MIT默认服务器)
步骤1:添加组件
在App Inventor 2设计视图中,从左侧组件面板的「Storage」分类中拖拽 CloudDB 组件到屏幕上。
步骤2:配置属性
| 属性 | 设置值 | 说明 |
|---|---|---|
RedisServer |
DEFAULT |
使用MIT默认服务器 |
RedisPort |
6381 |
默认端口,无需修改 |
Token |
不修改 | 系统自动填充认证令牌 |
UseSSL |
true |
默认服务器必须开启SSL |
ProjectID |
自动生成 | 每个项目唯一标识 |
提示: 使用MIT默认服务器时,所有属性保持默认即可,无需手动配置。
2.3 配置步骤(使用自建Redis服务器)
如果你需要完全掌控数据,可以搭建自己的Redis服务器:
步骤1:安装Redis
# Ubuntu/Debian
sudo apt update
sudo apt install redis-server
# CentOS
sudo yum install redis
# Docker方式(推荐)
docker run -d --name redis-clouddb \
-p 6381:6379 \
-v redis-data:/data \
redis:7 redis-server --appendonly yes --requirepass your_password_here
步骤2:配置Redis
编辑Redis配置文件(通常为 /etc/redis/redis.conf):
# 设置监听端口
port 6381
# 设置密码
requirepass your_secure_password
# 开启持久化
appendonly yes
appendfilename "appendonly.aof"
# 绑定地址(根据需要调整)
bind 0.0.0.0
步骤3:在App Inventor中配置
| 属性 | 设置值 | 说明 |
|---|---|---|
RedisServer |
你的服务器IP或域名 |
如 192.168.1.100 或 redis.example.com |
RedisPort |
6381 |
与服务器端口一致 |
Token |
your_secure_password |
Redis服务器密码 |
UseSSL |
根据服务器配置 | 如果服务器启用了SSL则为true |
ProjectID |
自定义 | 多项目可使用不同ProjectID隔离数据 |
2.4 数据读写积木块操作
存储数据
调用 CloudDB.StoreValue(
tag: "userName",
valueToStore: "张三"
)
当存储完成后,会触发 CloudDB.UpdateDone(tag, operation) 事件。
读取数据
调用 CloudDB.GetValue(
tag: "userName",
valueIfTagNotThere: ""
)
事件 CloudDB.GotValue(tag, value):
如果 tag = "userName":
设置 Label1.文本 为 value
注意:
GetValue是异步操作,不会直接返回值。你必须在GotValue事件中处理返回的数据。
监听数据变化
事件 CloudDB.DataChanged(tag, value):
// 当任何设备修改了数据,所有连接的设备都会收到此事件
设置 Label_Status.文本 为 合并文本("数据已更新:", tag, " = ", value)
列表操作
// 原子性追加元素到列表(多设备并发安全)
调用 CloudDB.AppendValueToList(
tag: "chatMessages",
itemToAdd: "你好!"
)
// 原子性获取并移除列表首元素(适合消息队列)
调用 CloudDB.RemoveFirstFromList(tag: "taskQueue")
事件 CloudDB.FirstRemoved(value):
设置 Label_Result.文本 为 合并文本("取出:", value)
获取所有标签
调用 CloudDB.GetTagList()
事件 CloudDB.TagList(value):
// value 是所有标签名的列表
设置 ListPicker1.元素 为 value
删除数据
// 删除指定标签的数据
调用 CloudDB.ClearTag(tag: "userName")
// 检查连接状态
设置 Label_Status.文本 为 CloudDB.CloudConnected()
2.5 完整示例:简易聊天应用
界面设计:
- TextBox_Chat:输入聊天消息
- Button_Send:发送按钮
- Label_Messages:显示聊天记录
积木块逻辑:
// Screen初始化
事件 Screen1.初始化():
调用 CloudDB.GetValue(tag: "chatHistory", valueIfTagNotThere: 空列表)
// 发送消息
事件 Button_Send.点击():
调用 CloudDB.AppendValueToList(
tag: "chatHistory",
itemToAdd: 合并文本(TextBox_Chat.文本)
)
设置 TextBox_Chat.文本 为 ""
// 收到历史消息
事件 CloudDB.GotValue(tag, value):
如果 tag = "chatHistory":
设置 Label_Messages.文本 为 合并文本列表(value, "\n")
// 实时监听新消息
事件 CloudDB.DataChanged(tag, value):
如果 tag = "chatHistory":
设置 Label_Messages.文本 为 合并文本列表(value, "\n")
三、FirebaseDB —— Google实时数据库
3.1 简介
FirebaseDB组件对接Google Firebase Realtime Database,提供实时数据同步能力。数据以JSON树形结构存储,支持离线缓存和自动同步。
核心特点:
- Google级别的稳定性和扩展性
- 真正的实时数据同步
- 离线缓存,网络恢复后自动同步
- 丰富的安全规则配置
- 免费额度充足(Spark计划)
3.2 Firebase项目创建
步骤1:注册Firebase
- 访问 Firebase控制台
- 使用Google账户登录
- 点击「添加项目」
- 输入项目名称(如
my-appinventor-app) - 选择是否启用Google Analytics(可选)
- 点击「创建项目」
步骤2:创建Realtime Database
- 在Firebase控制台左侧菜单中找到「Build」→「Realtime Database」
- 点击「Create Database」
- 选择数据库位置(建议选择离用户最近的区域)
- 选择安全规则模式:
- 测试模式:允许所有读写(开发阶段使用)
- 锁定模式:拒绝所有读写(生产环境推荐)
步骤3:获取配置信息
在Firebase项目设置中记录以下信息:
- 数据库URL:格式为
https://your-project-id-default-rtdb.firebaseio.com/ - Firebase Token:在Realtime Database的规则中配置
3.3 在App Inventor中配置FirebaseDB
步骤1:添加组件
在设计视图中,从「Storage」分类拖拽 FirebaseDB 组件到屏幕。
步骤2:配置属性
| 属性 | 设置值 | 说明 |
|---|---|---|
FirebaseToken |
从Firebase获取的Token | 项目设置中的Web API Key |
FirebaseURL |
数据库URL | https://xxx.firebaseio.com/ |
UseService |
false |
使用Token认证方式 |
3.4 Firebase安全规则配置
在Firebase控制台的「Realtime Database」→「Rules」中配置安全规则:
开发/测试阶段规则(允许所有读写):
{
"rules": {
".read": true,
".write": true
}
}
生产环境推荐规则(需要认证):
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
},
"public": {
".read": true,
".write": "auth !== null"
}
}
}
⚠️ 安全警告: 测试模式规则会在30天后自动过期。生产环境务必配置适当的安全规则,避免数据泄露。
3.5 数据读写积木块操作
存储数据
调用 FirebaseDB.StoreValue(
tag: "score",
valueToStore: 100
)
事件 FirebaseDB.DataChanged(tag, value):
// 数据存储成功或变更时触发
读取数据
调用 FirebaseDB.GetValue(
tag: "score",
valueIfTagNotThere: 0
)
事件 FirebaseDB.GotValue(tag, value):
如果 tag = "score":
设置 Label_Score.文本 为 合并文本("分数:", value)
删除数据
调用 FirebaseDB.ClearTag(tag: "score")
追加到列表
调用 FirebaseDB.AppendValueToList(
tag: "messages",
itemToAdd: "新消息"
)
移除列表首元素
调用 FirebaseDB.RemoveFirstFromList(tag: "taskQueue")
事件 FirebaseDB.FirstRemoved(value):
设置 Label_Result.文本 为 value
3.6 完整示例:实时排行榜
界面设计:
- TextBox_Name:输入玩家名
- TextBox_Score:输入分数
- Button_Submit:提交按钮
- Label_Leaderboard:显示排行榜
积木块逻辑:
// 初始化加载排行榜
事件 Screen1.初始化():
调用 FirebaseDB.GetValue(tag: "leaderboard", valueIfTagNotThere: 空列表)
// 提交分数
事件 Button_Submit.点击():
定义局部变量 entry = 合并文本(TextBox_Name.文本, ":", TextBox_Score.文本)
调用 FirebaseDB.AppendValueToList(
tag: "leaderboard",
itemToAdd: entry
)
// 收到数据
事件 FirebaseDB.GotValue(tag, value):
如果 tag = "leaderboard":
设置 Label_Leaderboard.文本 为 合并文本列表(value, "\n")
// 实时更新
事件 FirebaseDB.DataChanged(tag, value):
如果 tag = "leaderboard":
设置 Label_Leaderboard.文本 为 合并文本列表(value, "\n")
四、TinyWebDB —— 自建网络微数据库后台
4.1 简介
TinyWebDB是App Inventor 2中最灵活的云存储方案。它不绑定特定的云服务商,而是通过HTTP接口与你自己搭建的Web服务器通信。你可以使用PHP、Node.js、Python等任何后端技术来实现服务接口。
核心特点:
- 完全自主可控,数据存储在自己的服务器
- 可以使用MySQL、SQLite、MongoDB等任何数据库
- 可以实现复杂的业务逻辑(用户认证、数据过滤等)
- 可以部署在国内服务器(阿里云、腾讯云等),访问速度快
- 支持PHP、Node.js、Python、Java等后端技术
4.2 TinyWebDB API规范
TinyWebDB组件与后台服务之间通过标准HTTP POST请求通信,使用特定的JSON格式:
保存数据(storeavalue)
请求:
POST /api/storeavalue
Content-Type: application/x-www-form-urlencoded
tag=userName&value=张三
成功响应:
["STORED", "userName", "张三"]
获取数据(getvalue)
请求:
POST /api/getvalue
Content-Type: application/x-www-form-urlencoded
tag=userName
成功响应(数据存在):
["VALUE", "userName", "张三"]
成功响应(数据不存在):
["VALUE", "userName", ""]
4.3 在App Inventor中配置TinyWebDB
步骤1:添加组件
在设计视图中,从「Storage」分类拖拽 TinyWebDB 组件到屏幕。
步骤2:配置属性
| 属性 | 设置值 | 说明 |
|---|---|---|
ServiceURL |
http://你的服务器地址/api/ |
你的后台服务URL |
注意: ServiceURL必须以
/结尾。如果使用HTTPS,确保服务器SSL证书有效。
4.4 PHP后台实现方案
方案一:基于文件的简易存储
以下PHP代码使用JSON文件存储数据,适合小型应用:
文件结构:
/var/www/html/tinywebdb/
├── api/
│ ├── index.php # API入口
│ └── data/
│ └── store.json # 数据文件
api/index.php:
<?php
/**
* TinyWebDB API - 文件存储版
* 适用于小型应用,无需数据库
*/
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
$dataFile = __DIR__ . '/data/store.json';
// 确保数据目录存在
if (!is_dir(__DIR__ . '/data')) {
mkdir(__DIR__ . '/data', 0755, true);
}
// 读取现有数据
function loadData($file) {
if (file_exists($file)) {
$content = file_get_contents($file);
return json_decode($content, true) ?: [];
}
return [];
}
// 保存数据
function saveData($file, $data) {
file_put_contents($file, json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
}
// 获取POST参数
$tag = isset($_POST['tag']) ? $_POST['tag'] : '';
$value = isset($_POST['value']) ? $_POST['value'] : '';
// 路由处理
$action = basename($_SERVER['REQUEST_URI']);
if ($action === 'storeavalue') {
// 保存数据
if (empty($tag)) {
echo json_encode(["ERROR", "Tag cannot be empty"]);
exit;
}
$data = loadData($dataFile);
$data[$tag] = $value;
saveData($dataFile, $data);
echo json_encode(["STORED", $tag, $value]);
} elseif ($action === 'getvalue') {
// 获取数据
if (empty($tag)) {
echo json_encode(["ERROR", "Tag cannot be empty"]);
exit;
}
$data = loadData($dataFile);
$resultValue = isset($data[$tag]) ? $data[$tag] : "";
echo json_encode(["VALUE", $tag, $resultValue]);
} else {
echo json_encode(["ERROR", "Unknown action: $action"]);
}
?>
方案二:基于MySQL的完整方案
适合生产环境,支持高并发:
数据库初始化(SQL):
CREATE DATABASE IF NOT EXISTS tinywebdb
DEFAULT CHARACTER SET utf8mb4
DEFAULT COLLATE utf8mb4_unicode_ci;
USE tinywebdb;
CREATE TABLE IF NOT EXISTS store (
id INT AUTO_INCREMENT PRIMARY KEY,
tag VARCHAR(255) NOT NULL,
value TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY idx_tag (tag)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
api/index.php:
<?php
/**
* TinyWebDB API - MySQL存储版
* 适用于生产环境
*/
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
// 数据库配置
$dbHost = 'localhost';
$dbName = 'tinywebdb';
$dbUser = 'tinywebdb_user';
$dbPass = 'your_secure_password';
// 可选:简易API密钥认证
$apiKey = 'your_api_key_here';
$enableAuth = false; // 设为 true 启用认证
// 认证检查
if ($enableAuth) {
$requestKey = isset($_SERVER['HTTP_X_API_KEY']) ? $_SERVER['HTTP_X_API_KEY'] : '';
if ($requestKey !== $apiKey) {
http_response_code(401);
echo json_encode(["ERROR", "Unauthorized"]);
exit;
}
}
// 数据库连接
try {
$pdo = new PDO(
"mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4",
$dbUser,
$dbPass,
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
} catch (PDOException $e) {
echo json_encode(["ERROR", "Database connection failed"]);
exit;
}
// 获取POST参数
$tag = isset($_POST['tag']) ? $_POST['tag'] : '';
$value = isset($_POST['value']) ? $_POST['value'] : '';
// 路由处理
$action = basename($_SERVER['REQUEST_URI']);
if ($action === 'storeavalue') {
if (empty($tag)) {
echo json_encode(["ERROR", "Tag cannot be empty"]);
exit;
}
// 使用 INSERT ... ON DUPLICATE KEY UPDATE 实现 upsert
$stmt = $pdo->prepare(
"INSERT INTO store (tag, value) VALUES (:tag, :value)
ON DUPLICATE KEY UPDATE value = :value2, updated_at = NOW()"
);
$stmt->execute([
':tag' => $tag,
':value' => $value,
':value2'=> $value
]);
echo json_encode(["STORED", $tag, $value]);
} elseif ($action === 'getvalue') {
if (empty($tag)) {
echo json_encode(["ERROR", "Tag cannot be empty"]);
exit;
}
$stmt = $pdo->prepare("SELECT value FROM store WHERE tag = :tag");
$stmt->execute([':tag' => $tag]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$resultValue = $row ? $row['value'] : "";
echo json_encode(["VALUE", $tag, $resultValue]);
} else {
echo json_encode(["ERROR", "Unknown action: $action"]);
}
?>
4.5 Node.js后台实现方案
如果你更习惯使用Node.js,以下是等效的后台实现:
安装依赖:
mkdir tinywebdb-server && cd tinywebdb-server
npm init -y
npm install express body-parser
server.js:
/**
* TinyWebDB API - Node.js实现
* 使用文件存储(可替换为MongoDB/MySQL)
*/
const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs');
const path = require('path');
const app = express();
const PORT = process.env.PORT || 3000;
const DATA_FILE = path.join(__dirname, 'data', 'store.json');
// 中间件
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// CORS支持
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
// 确保数据目录和文件存在
function ensureDataFile() {
const dir = path.dirname(DATA_FILE);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
if (!fs.existsSync(DATA_FILE)) {
fs.writeFileSync(DATA_FILE, '{}', 'utf8');
}
}
// 读取数据
function loadData() {
ensureDataFile();
const content = fs.readFileSync(DATA_FILE, 'utf8');
return JSON.parse(content);
}
// 保存数据
function saveData(data) {
ensureDataFile();
fs.writeFileSync(DATA_FILE, JSON.stringify(data, null, 2), 'utf8');
}
// 保存数据API
app.post('/api/storeavalue', (req, res) => {
const tag = req.body.tag || '';
const value = req.body.value || '';
if (!tag) {
return res.json(['ERROR', 'Tag cannot be empty']);
}
const data = loadData();
data[tag] = value;
saveData(data);
res.json(['STORED', tag, value]);
});
// 获取数据API
app.post('/api/getvalue', (req, res) => {
const tag = req.body.tag || '';
if (!tag) {
return res.json(['ERROR', 'Tag cannot be empty']);
}
const data = loadData();
const resultValue = data.hasOwnProperty(tag) ? data[tag] : '';
res.json(['VALUE', tag, resultValue]);
});
// 启动服务器
app.listen(PORT, () => {
console.log(`TinyWebDB Server running on http://localhost:${PORT}`);
console.log(`API endpoints:`);
console.log(` POST http://localhost:${PORT}/api/storeavalue`);
console.log(` POST http://localhost:${PORT}/api/getvalue`);
});
启动服务器:
node server.js
# 或使用 pm2 保持后台运行
npm install -g pm2
pm2 start server.js --name tinywebdb
然后在App Inventor的TinyWebDB组件中设置:
ServiceURL = http://你的服务器IP:3000/api/
4.6 TinyWebDB数据读写积木块操作
存储数据
调用 TinyWebDB.StoreValue(
tag: "userName",
valueToStore: "张三"
)
事件 TinyWebDB.ValueStored():
// 数据存储成功
设置 Label_Status.文本 为 "保存成功"
读取数据
调用 TinyWebDB.GetValue(tag: "userName")
事件 TinyWebDB.GotValue(tag, valueFromWebDB):
如果 tag = "userName":
设置 Label_Name.文本 为 valueFromWebDB
注意: 与CloudDB/FirebaseDB类似,
GetValue是异步操作,必须在GotValue事件中处理返回数据。
错误处理
事件 TinyWebDB.WebServiceError(message):
设置 Label_Error.文本 为 合并文本("网络错误:", message)
4.7 完整示例:用户登录注册系统
界面设计:
- TextBox_Username:用户名输入
- TextBox_Password:密码输入
- Button_Register:注册按钮
- Button_Login:登录按钮
- Label_Status:状态提示
积木块逻辑:
// 注册
事件 Button_Register.点击():
如果 TextBox_Username.文本 = "" 或 TextBox_Password.文本 = "":
设置 Label_Status.文本 为 "用户名和密码不能为空"
否则:
// 先检查用户是否已存在
调用 TinyWebDB.GetValue(
tag: 合并文本("user:", TextBox_Username.文本)
)
// 读取结果
事件 TinyWebDB.GotValue(tag, valueFromWebDB):
如果 包含文本(tag, "user:"):
如果 valueFromWebDB = "":
// 用户不存在,可以注册
调用 TinyWebDB.StoreValue(
tag: 合并文本("user:", TextBox_Username.文本),
valueToStore: TextBox_Password.文本
)
设置 Label_Status.文本 为 "注册成功!"
否则:
// 用于登录验证
如果 valueFromWebDB = TextBox_Password.文本:
设置 Label_Status.文本 为 "登录成功!"
否则:
设置 Label_Status.文本 为 "密码错误"
// 登录
事件 Button_Login.点击():
调用 TinyWebDB.GetValue(
tag: 合并文本("user:", TextBox_Username.文本)
)
五、Web组件 —— 通用HTTP数据交互
除了以上专门的数据库组件,App Inventor 2还提供了 Web 组件,可以与任何HTTP API进行数据交互,适合与自建PHP/Node.js服务器进行复杂数据交换。
5.1 发送GET请求
// 设置请求URL
设置 Web1.Url 为 "http://你的服务器/api/getData.php?key=value"
调用 Web1.执行GET请求()
事件 Web1.收到文本(responseCode, responseContent):
如果 responseCode = 200:
设置 Label_Result.文本 为 responseContent
5.2 发送POST请求
// 设置请求URL和参数
设置 Web1.Url 为 "http://你的服务器/api/saveData.php"
调用 Web1.执行POST请求(
文本: 合并文本("name=", TextBox_Name.文本, "&score=", TextBox_Score.文本),
编码: "UTF-8"
)
事件 Web1.收到文本(responseCode, responseContent):
如果 responseCode = 200:
设置 Label_Status.文本 为 "提交成功"
5.3 PHP后台接收示例
<?php
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
$method = $_SERVER['REQUEST_METHOD'];
if ($method === 'GET') {
$key = isset($_GET['key']) ? $_GET['key'] : '';
// 处理GET请求,查询数据
$result = ["status" => "ok", "data" => "查询结果"];
echo json_encode($result, JSON_UNESCAPED_UNICODE);
} elseif ($method === 'POST') {
$name = isset($_POST['name']) ? $_POST['name'] : '';
$score = isset($_POST['score']) ? $_POST['score'] : '';
// 处理POST请求,保存数据
$result = ["status" => "ok", "message" => "保存成功"];
echo json_encode($result, JSON_UNESCAPED_UNICODE);
}
?>
六、安全最佳实践
6.1 数据传输安全
| 措施 | 说明 |
|---|---|
| 使用HTTPS | 生产环境务必启用SSL证书(Let’s Encrypt免费获取) |
| API密钥认证 | 自建后台应实现API Key验证 |
| 输入验证 | 后台必须验证和过滤所有输入数据 |
| 速率限制 | 防止恶意请求,建议每IP每分钟限制请求数 |
6.2 Firebase安全规则进阶
{
"rules": {
// 公开只读数据
"public": {
".read": true,
".write": false
},
// 已认证用户可读写
"users": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
},
// 限流:每分钟最多10次写入
"messages": {
".read": true,
".write": "auth != null && newData.exists()",
"$messageId": {
".validate": "newData.hasChildren(['text', 'timestamp'])"
}
}
}
}
6.3 自建后台安全加固
Nginx反向代理配置示例:
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
# 限流
limit_req_zone $binary_remote_addr zone=api:10m rate=30r/m;
location /api/ {
limit_req zone=api burst=10 nodelay;
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
七、方案选择建议
根据不同的应用场景,推荐以下选择策略:
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 快速原型开发 | CloudDB(MIT默认) | 零配置,开箱即用 |
| 教学演示 | CloudDB(MIT默认) | 无需额外搭建,适合课堂教学 |
| 实时聊天/协作 | FirebaseDB | 原生实时同步,离线支持 |
| 排行榜/成绩统计 | CloudDB 或 FirebaseDB | 原子操作保证并发安全 |
| 国内用户为主 | TinyWebDB自建后台 | 部署在国内服务器,访问速度快 |
| 需要复杂业务逻辑 | TinyWebDB + Web组件 | 完全自定义后台逻辑 |
| 数据报表/表单 | Google Spreadsheet | 天然支持表格操作 |
| 企业级应用 | TinyWebDB + 自建后台 | 数据安全可控,符合合规要求 |
八、常见问题(FAQ)
Q1:CloudDB的MIT默认服务器有容量限制吗?
MIT默认服务器是共享资源,适合开发和测试。对于生产环境或高并发应用,建议自建Redis服务器。
Q2:Firebase在国内能正常访问吗?
Firebase服务在国内访问可能不稳定。如果目标用户在国内,建议使用CloudDB(自建Redis)或TinyWebDB(自建后台)方案。
Q3:TinyWebDB的ServiceURL可以配置多个吗?
每个TinyWebDB组件只能配置一个ServiceURL。如果需要连接多个服务,可以添加多个TinyWebDB组件。
Q4:如何在不同应用之间共享CloudDB数据?
CloudDB的数据隔离基于ProjectID。要跨应用共享数据,可以使用相同的Token值。将一个应用的Token复制到另一个应用的CloudDB组件中即可实现数据共享。
Q5:自建后台可以用云服务器吗?
可以。阿里云ECS、腾讯云CVM、华为云ECS等国内云服务器都可以部署TinyWebDB后台。推荐使用Ubuntu系统,搭配Nginx反向代理和Let’s Encrypt免费SSL证书。
九、参考资源
© 2024 App Inventor 2 中文网。本文基于MIT官方文档编写,仅供学习参考。
扫码添加客服咨询