hydrogen-js-sdk 是 同一个 SDK 文件 Bmob- 支持以下所有宿主环境,无平台分支代码:
> 本 skill 只覆盖新版 hydrogen-js-sdk(Bmob.Query('X') Promise 风格,3.0+)。基于 Backbone.js 的旧 bmob-min.js(Bmob.Object.extend("X") callback 风格)不要用,也不要回退。
1. 初始化支持两种方式(hydrogen-js-sdk 3.0+ 均兼容;按场景二选一,不要混用):
方式 A — Secret Key + API 安全码(推荐:浏览器 / 小程序 / 公开客户端,SDK 内部走加密授权):
Bmob.initialize("你的Secret Key", "你的API 安全码");
方式 B — Application ID + REST API Key(3.0 起正式兼容;适合已有 1.x/2.x 项目迁移、或与服务端 REST 共用同一套 Key):
Bmob.initialize("你的Application ID", "你的REST API Key");
https://api.codenow.cn(见 bmob-database-restful)。> 2.x 时代方式 B 功能受限;3.0+ 两种初始化等价可用。公开 bundle 仍优先方式 A(REST API Key 可被抓包)。
2. 不要 commit 真实密钥进 git;CDN / dist 不要写死 SDK 版本号。 密钥用环境变量(Vite import.meta.env.VITE_BMOB_、Next.js process.env.NEXT_PUBLIC_BMOB_、小程序构建期注入等)。dist 文件名为 Bmob-,有打包工具时用 npm install hydrogen-js-sdk;纯 CDN 浏览器场景用 jsDelivr API 动态取 tags.latest 再拼 URL(见 references/platform-init.md)。禁止在示例里写 @2.7.3 这类会过期的具体版本。
3. 默认查询返回 100 条,最大 1000。需要更多用 skip + limit 分页或走 BQL(bmob-bql skill)。
4. 三个保留字段不能手动写入:objectId、createdAt、updatedAt。读 objectId 时用 res.objectId(不是 id)。
5. 时间字段比较的精度:createdAt / updatedAt 在服务器是微秒精度,应用层做时间比较时要 +1 秒。
Bmob.debug(true) 仅在小程序开发时使用,上线前删掉。request 合法域名至少添加 https://api.bmobcloud.com(见 references/platform-init.md 微信小程序段)。import Bmob from "hydrogen-js-sdk" 不会生效。bmob-acl-and-roles(P1)。Bmob.User.login 在小程序里要先调用 wx.login() 获取 code,否则会话拿不到 sessionToken。默认推荐 方式 A(Secret Key + API 安全码);3.0+ 亦可用 方式 B(Application ID + REST API Key),见上方核心原则。
import Bmob from "hydrogen-js-sdk";
Bmob.initialize("你的Secret Key", "你的API 安全码");
// 或:Bmob.initialize("你的Application ID", "你的REST API Key");
详细的 8 种宿主环境引入方式见 references/platform-init.md。
const query = Bmob.Query("GameScore");
query.set("score", 1337);
query.set("playerName", "bmob");
query.set("cheatMode", false);
query.save().then((res) => {
console.log(res.objectId, res.createdAt);
});
const query = Bmob.Query("GameScore");
query.get("7ecd253a25").then((res) => {
console.log(res);
});
const query = Bmob.Query("GameScore");
query.set("id", "7ecd253a25"); // 注意 set("id", objectId)
query.set("score", 9999);
query.save().then((res) => {
console.log(res.updatedAt);
});
const query = Bmob.Query("GameScore");
query.destroy("7ecd253a25").then((res) => {
console.log(res); // { msg: "ok" }
});
const query = Bmob.Query("GameScore");
query.get("7ecd253a25").then((res) => {
res.unset("cover");
res.save();
});
const query = Bmob.Query("GameScore");
query.find().then((res) => {
console.log(res);
});
equalTo(field, op, value),op 可以是 "==" / "!=" / ">" / ">=" / "<" / "<="。
const query = Bmob.Query("GameScore");
query.equalTo("score", ">", 100);
query.equalTo("cheatMode", "==", false); // 多个条件 = AND
query.limit(20);
query.skip(0);
query.order("-score"); // 降序
query.find().then(console.log);
const query = Bmob.Query("GameScore");
const q1 = query.equalTo("score", ">", 150);
const q2 = query.equalTo("score", "<", 5);
query.or(q1, q2);
query.find().then(console.log);
const query = Bmob.Query("Post");
query.select("title");
query.find().then(console.log);
query.containedIn("playerName", ["Bmob", "Codenow", "JS"]);
query.notContainedIn("playerName", ["spam"]);
query.exists("score"); // 含此字段
query.doesNotExist("score"); // 不含此字段
const query = Bmob.Query("diary");
query.count().then((n) => console.log(`共 ${n} 条`));
query.count(100).then((arr) => console.log("最多返回 100 条记录数据 + count"));
const query = Bmob.Query("Post");
query.get("objectId").then((res) => {
res.increment("likes"); // +1
res.increment("likes", 5); // +5(支持负数)
res.save();
});
const query = Bmob.Query("Diary");
query.add("DiaryType", ["public"]); // 末尾追加
query.addUnique("DiaryType", ["secret"]); // 去重追加
query.save();
query.get("objectId").then((res) => {
res.remove("DiaryType", ["secret"]); // 删除元素
res.save();
});
| 主题 | 路径 |
|---|---|
| --- | --- |
| 8 种宿主环境的初始化差异(浏览器 / Node / 微信/支付宝/字节/QQ/百度小程序 / 快应用 / Cocos Creator / Electron) | references/platform-init.md |
| Pointer / Relation 一对多 / 多对多 | references/pointer-and-relation.md |
复杂子查询($inQuery / $notInQuery)、模糊查询、地理位置查询 | references/query.md |
| 实时数据订阅(仅小程序 / Web)+ WebSocket | references/realtime.md |
| 批量操作(≤ 50) | references/batch.md |
如果用户在 IDE 里配置了 Bmob MCP,写代码前先调用 get_project_tables 拿到真实 schema,避免:
{"__type":"Pointer","className":"X","objectId":"..."})sequenceDiagram
autonumber
participant Dev as Developer
participant Agent as Agent
participant MCP as bmob-mcp
participant Code as bmob-database-javascript
Dev->>Agent: "Next.js 项目里加 Bmob 文章列表"
Agent->>MCP: get_project_tables()
MCP-->>Agent: {Article: {title:String, content:String, author:Pointer(_User)}}
Agent->>Code: 按真实 schema 生成 Bmob.Query("Article") 代码
Code-->>Dev: 完整可运行代码(含 ACL 提示)
| 现象 | 排查 |
|---|---|
| --- | --- |
Bmob is undefined | 没引入 SDK;或 Node.js 用了压缩版(必须用源码 require('hydrogen-js-sdk/src/lib/app.js')) |
| 初始化报 401 | 方式 A:Secret Key 或 API 安全码与控制台不一致;方式 B:Application ID 或 REST API Key 错;或两种方式的参数混用(例如用 Application ID 当 Secret Key 传) |
| 写入成功但字段值不见 | 字段名拼错(schemaless 不报错);先 get_project_tables 比对 |
| 查询返回数据少 | 默认 100 条上限;用 query.limit(1000) 或分页 |
set("id", ...) 没生效 | 更新时必须用 set("id", objectId)(不是 set("objectId", ...)) |
| 时间范围查询少一条 | 服务端时间是微秒精度,区间右端 +1 秒 |
| 小程序请求失败 | 先检查微信后台 request 合法域名是否已添加 https://api.bmobcloud.com;若 SDK 是 npm 引入,还要在微信开发者工具执行“工具 --> 构建 npm”后再编译运行 |
| Promise 一直 pending | 调用了不存在的方法名(hydrogen 不抛错只挂起);对照 完整 API |
| 9015 报错 | 见 bmob-error-codes 的 9015 专题 |
bmob-error-codesbmob-mcp共 1 个版本