暮鼓集 行走集
原作于2016年08月29日
1. Overview
Firebase数据库为Key-value的JSON Tree
限制 子节点深度 32 Key长度 768bytes 子节点大小 10M 写入 16M,(REST方式)256M Read操作的Node 100M
Backup/Restore 系统每日自动备份,由硬件层完成,保存60天,这些备份主要用于灾难恢复,但是开发者也可用于紧急恢复。 提供私有备份,可以备份到Google Clould Storage或Amazon Simple Storage Solution bucket,这也是硬件层完成,不影响性能,这需要升级到Bonfire,Blaze或Inferno计划。 也可以通过REST API来手动备份,对于小于200M的DB,直接读取root,否则要分片读取。
实时同步到所有连接的客户端
2. 保存数据
set() - 将JSON数据保存到指定路径,覆盖掉该路径上包括子节点在内的所有数据 返回一个该位置引用对象
update() - 更新数据但不会覆盖全部 可以同时更新多个 需要注意 “A/B:value”的形式
可以为set与update增加完成Complete回调
push() - 在数据中加入一个数据列表,每次调用push()数据库将生成一个ID,这个ID基于时间戳, 使用.key()获取这个ID
JS
var data = { 'name':name, 'addr':addr, 'tel':tel };
var ref1 = firebase.database().ref('restaurants');
var ref2 = ref1.push();
ref2.set(data);
var path = ref2.toString();
transaction() - 事务
offline writes Firebase在本地维护了一个本地版本,在写数据时都是先保存到本地,所以,在断网时也可以保存数据,当网络恢复时可以同步数据。这些都是自动完成的而无须写代码实现。
3 读取数据
Firebase 通过异步侦听方式获取数据,Firebase定义了两种侦听器与五个侦听事件
public interface ValueEventListener {
// 读取和侦听对路径的全部内容所做的更改
void onDataChange(DataSnapshot var1);
void onCancelled(DatabaseError var1);
}
public interface ChildEventListener{
//检索项目列表,或侦听项目列表中是否添加了新项目
void onChildAdded(DataSnapshot snapshot, String previousChild);
// 侦听对列表中的项目所做的更改
void onChildChanged(DataSnapshot dataSnapshot, String s);
// 侦听正从列表中删除的项目
void onChildRemoved(DataSnapshot dataSnapshot) {}
// 与经过排序的数据配合使用,从而侦听对项目优先级所做的更改
void onChildMoved(DataSnapshot dataSnapshot, String s);
void onCancelled(DatabaseError databaseError) { }
}
两种侦听器的区别是,ValueEventListener侦听某一节点下的全部变化,而ChildEventListener侦听子节点的变化。ValueEventListener只有一个Callback的方法onDataChange,ChildEventListener则有多个,控制更为精细,但是需要多个Callback方法组合使用才能获得对node进行增删改查的完整侦听。
侦听器使DataSnapShop来传递数据,如果没有任何数据,返回null。
应小心的设计侦听的node的层级,仅在需要观察更改的最低级别附加侦听器,避免加在根节点上。
读取一次
addValueEventListener();
addListenerForSingleValueEvent()
排序
String myUserId = getUid();
Query myTopPostsQuery = databaseReference.child("user-posts").child(myUserId)
.orderByChild("starCount");
过滤
Query recentPostsQuery = databaseReference.child("posts")
.limitToFirst(100);
4 设置规则
使用灵活的,基于表达式的,类JavaScript符号定义了数据如何结构化,如何索引和何时读写 使用Web Console或Command Line来设置,后一种对程序自动部署很有用 .read - 是否以及何时允许读 .write - 是否以及何时允许写 .validate - 设置值的样子,是否允许有Child Node,以及类型 .indexOn
预定义变量 now, root, new Data, data, $variables, auth
对Public开放
{
"rules": {
".read": true,
".write": true
}
}
仅对鉴权用户开放
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
{
"rules": {
"messages": {
"$message": {
// only messages from the last ten minutes can be read
".read": "data.child('timestamp').val() > (now - 600000)",
// new messages must have a string content and a number timestamp
".validate": "newData.hasChildren(['content', 'timestamp']) && newData.child('content').isString() && newData.child('timestamp').isNumber()"
}
}
}
}
限制为1900-2000的YYYY-MM-DD
".validate": "newData.isString() &&
newData.val().matches(/^(19|20)[0-9][0-9][-\\/. ](0[1-9]|1[012])[-\\/. ](0[1-9]|[12][0-9]|3[01])$/)"
层级控制,浅层的规则覆盖深层,最浅层则是root 如果一个node下有任何子node设置为读false,那么读取这个node就会失败
限制用户访问自己的数据 一个常用的做法是所有的user放在users节点下,并使用如下规则来访问自己的数据