Ember 数据 Firebase 规则混乱
Ember Data Firebase rules confusion
我正在开始我的第一个 Ember/Firebase 应用程序,但在查找超出 public 数据的文档时遇到了问题。
我的目标是拥有一个应用程序,登录用户可以在其中创建和查看自己的数据。我看到 Firebase 针对这种情况建议了这条规则:
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
但是我找不到任何关于这在 Ember 端如何工作的信息。例如,假设我有一个要保存的 "entry" 模型:
save(model) {
model.save().then( () => {
this.transitionToRoute('index');
}, error => {
console.error(`error: ${error}`);
})
},
不确定我是否需要在模型中存储 uid?
然后如果我希望用户获得他们自己的条目列表:
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.store.findAll('entry');
}
});
这会产生以下错误:
ember.debug.js:30610 Error while processing route: index permission_denied at /entries: Client doesn't have permission to access the desired data. Error: permission_denied at /entries: Client doesn't have permission to access the desired data.
此时我不确定我应该做什么 –– 我是否需要构建自定义 URL 或在我的 firebase 适配器中添加命名空间以添加 users/xxx 前缀?或者等等?
找不到任何 documentation/tutorials/walkthroughs 涵盖 public read/write 数据以外的任何内容。
我最终完成了这项工作。它基本上归结为在登录后将来自 Firebase auth 的 uid 存储在服务中(我添加 ember-local-storage 以防页面刷新),然后向应用程序适配器添加 pathForType 方法以将所有用户数据嵌套在 users/$ 下{uid},因此在 firebase 中,数据以这种配置结束:users/${uid}/entries/${entry_id}.
application/adapter.js
import FirebaseAdapter from 'emberfire/adapters/firebase';
import Ember from 'ember';
export default FirebaseAdapter.extend({
/* inject service to access uid */
journalist: Ember.inject.service('journalist'),
/* path for type nests /entries under users/${uid} */
pathForType(type) {
let uid = this.get('journalist.uid');
let path = Ember.String.pluralize(type);
return `users/${uid}/${path}`;
}
});
application/route.js
import Ember from 'ember';
export default Ember.Route.extend({
/* injecting service to set uid */
journalist: Ember.inject.service('journalist'),
beforeModel() {
return this.get('session').fetch().catch();
},
actions: {
signIn(provider) {
this.get('session').open('firebase', {provider: provider}).then(data => {
/* setting uid in service for later retrieval elsewhere */
this.get('journalist').setUID(data.uid);
this.transitionTo('entries');
});
},
signOut() {
this.get('session').close().then(() => this.transitionTo('application'));
}
}
});
entries/route.js
import Ember from 'ember';
export default Ember.Route.extend({
/* nothing special required for ember data save, findAll, etc, adapter takes care of everything */
model() {
return this.store.findAll('entry');
}
});
services/journalist.js:
import Ember from 'ember';
import { storageFor } from 'ember-local-storage';
export default Ember.Service.extend({
uid: null,
localStore: storageFor('journalist-session'),
init() {
const localStore = this.get('localStore');
this.set('uid', localStore.get('uid'));
},
setUID(id) {
this.set('uid', id);
this.set('localStore.uid', id);
}
});
storages/journalist-session:
import StorageObject from 'ember-local-storage/local/object';
const Storage = StorageObject.extend();
Storage.reopenClass({
initialState() {
return {
uid: null
};
}
});
export default Storage;
firebase 规则:
{
"rules": {
"users": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
}
}
}
我正在开始我的第一个 Ember/Firebase 应用程序,但在查找超出 public 数据的文档时遇到了问题。
我的目标是拥有一个应用程序,登录用户可以在其中创建和查看自己的数据。我看到 Firebase 针对这种情况建议了这条规则:
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
但是我找不到任何关于这在 Ember 端如何工作的信息。例如,假设我有一个要保存的 "entry" 模型:
save(model) {
model.save().then( () => {
this.transitionToRoute('index');
}, error => {
console.error(`error: ${error}`);
})
},
不确定我是否需要在模型中存储 uid?
然后如果我希望用户获得他们自己的条目列表:
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.store.findAll('entry');
}
});
这会产生以下错误:
ember.debug.js:30610 Error while processing route: index permission_denied at /entries: Client doesn't have permission to access the desired data. Error: permission_denied at /entries: Client doesn't have permission to access the desired data.
此时我不确定我应该做什么 –– 我是否需要构建自定义 URL 或在我的 firebase 适配器中添加命名空间以添加 users/xxx 前缀?或者等等?
找不到任何 documentation/tutorials/walkthroughs 涵盖 public read/write 数据以外的任何内容。
我最终完成了这项工作。它基本上归结为在登录后将来自 Firebase auth 的 uid 存储在服务中(我添加 ember-local-storage 以防页面刷新),然后向应用程序适配器添加 pathForType 方法以将所有用户数据嵌套在 users/$ 下{uid},因此在 firebase 中,数据以这种配置结束:users/${uid}/entries/${entry_id}.
application/adapter.js
import FirebaseAdapter from 'emberfire/adapters/firebase';
import Ember from 'ember';
export default FirebaseAdapter.extend({
/* inject service to access uid */
journalist: Ember.inject.service('journalist'),
/* path for type nests /entries under users/${uid} */
pathForType(type) {
let uid = this.get('journalist.uid');
let path = Ember.String.pluralize(type);
return `users/${uid}/${path}`;
}
});
application/route.js
import Ember from 'ember';
export default Ember.Route.extend({
/* injecting service to set uid */
journalist: Ember.inject.service('journalist'),
beforeModel() {
return this.get('session').fetch().catch();
},
actions: {
signIn(provider) {
this.get('session').open('firebase', {provider: provider}).then(data => {
/* setting uid in service for later retrieval elsewhere */
this.get('journalist').setUID(data.uid);
this.transitionTo('entries');
});
},
signOut() {
this.get('session').close().then(() => this.transitionTo('application'));
}
}
});
entries/route.js
import Ember from 'ember';
export default Ember.Route.extend({
/* nothing special required for ember data save, findAll, etc, adapter takes care of everything */
model() {
return this.store.findAll('entry');
}
});
services/journalist.js:
import Ember from 'ember';
import { storageFor } from 'ember-local-storage';
export default Ember.Service.extend({
uid: null,
localStore: storageFor('journalist-session'),
init() {
const localStore = this.get('localStore');
this.set('uid', localStore.get('uid'));
},
setUID(id) {
this.set('uid', id);
this.set('localStore.uid', id);
}
});
storages/journalist-session:
import StorageObject from 'ember-local-storage/local/object';
const Storage = StorageObject.extend();
Storage.reopenClass({
initialState() {
return {
uid: null
};
}
});
export default Storage;
firebase 规则:
{
"rules": {
"users": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
}
}
}