我开始使用我的第一个Ember / Firebase应用程序,并且无法找到超出公共数据的文档。
我的目标是拥有一个应用程序,其中已签名的用户可以创建和查看自己的数据。我看到Firebase为这种情况建议了这条规则:
{
"rules": {
"users": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
但是我无法找到有关它如何在Ember端工作的任何信息。例如,假设我有一个我要保存的“入口”模型:
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处理路由时出错:index = permission / index:客户端无权访问所需数据。错误:/ entries处的permission_denied:客户端无权访问所需数据。
此时我不确定我应该做什么 - 我是否需要在我的firebase适配器中构建自定义URL或添加命名空间以添加users / xxx前缀?还是等等?
找不到涵盖公共读/写数据之外的任何文档/教程/演练。
答案 0 :(得分:2)
我最终完成了这项工作。它基本上归结为在登录后将Firebase auth中的uid存储在服务中(我在页面刷新的情况下添加了ember-local-storage),然后将pathForType方法添加到应用程序适配器以将所有用户数据嵌套在users / $下{uid},因此firebase数据最终会在此配置中结束:users / $ {uid} / entries / $ {entry_id}。
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}`;
}
});
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'));
}
}
});
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');
}
});
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);
}
});
import StorageObject from 'ember-local-storage/local/object';
const Storage = StorageObject.extend();
Storage.reopenClass({
initialState() {
return {
uid: null
};
}
});
export default Storage;
{
"rules": {
"users": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
}
}
}