我刚开始尝试使用Firebase。当你习惯了关系数据库时,它真的很棒!
我正在尝试设计一个应用程序,允许用户通过条形码或名称搜索膳食并检索卡路里数量。此外,我需要能够存储用户食用的食物,并最终每天,每周或每月检索用户食用的食物。
我认为每餐都有一个唯一的ID(例如M1234 for Pizza),然后我有2个查找部分 - 一个是条形码,一个是名字,所以应该有希望覆盖搜索功能。
每个用户都会按照日期在吃完的“表格”中存储食物(Firebase数据库中“表格”的正确用语是什么?),只是按照ID来参考用餐。
这就是我设计数据库的方式。
{
// Here are the users.
"users": {
"mchen": {
"name": "Mary Chen",
"email": "mary@chen.com",
}
},
...
},
// Here are the meals eaten by date.
"eaten": {
"mchen": {
// index Mary's meals in her profile /eaten/mchen/meals/20161217 should return 'M1234' (pizza) and 'M8765' (chips)
"meals": {
"20161217": {
"M1234": true,
"M8765": true
},
"20161218": {
"M2222": true,
"M8765": true
}
},
...
},
// Here are the meals with calorie information.
"meals": {
"M1234": {
"name": "Pizza"
"calories": 400
},
"M2222": {
"name": "Curry"
"calories": 250
},
"M8765": {
"name": "Chips"
"calories": 100
},
},
// Here is the barcode lookup
"barcode-lookup": {
"12345678": {
"id": "M1234"
},
"87654321": {
"id": "M2222"
},
"11223344": {
"id": "M8765"
}
},
// Here is the name lookup
"name-lookup": {
"Chips": {
"id": "M8765"
},
"Pizza": {
"id": "M1234"
},
"Curry": {
"id": "M2222"
}
}
}
看起来合理还是有明显的缺陷?
答案 0 :(得分:1)
结构看起来很好(虽然我会让firebase生成id)。唯一不会像你期望的那样工作的是搜索。根据您的数据,如果我搜索pizza
,您将无法编写将返回Pizza条目的查询。我的建议是使用Algolia(或类似的东西)进行搜索或使用您的名称lowerCased滚动另一个密钥,以使查询可以工作。运行自己的唯一问题是,您将无法搜索izz
之类的内容并让Pizza出现。有关如何进行搜索,请参阅我的回答Firebase - How can I filter similarly to equalTo() but instead check if it contains the value?。
答案 1 :(得分:1)
您需要利用.childByAutoId()并让Firebase创建父键名称。最佳做法是将您的子数据与父节点取消关联,并允许Firebase创建随机的'父母的关键是这样做。
除此之外,通常创建/ users节点,每个用户的父节点将是Firebase在首次创建用户时创建的uid。
在您的原始结构中,我已经将条形码和名称查找整合到以下结构中以降低复杂性。
dining
-Yuiia09skjspo
dining_timestamp: "20161207113010"
Y79joa90ksss: true
Yjs9990kokod: true
user: uid_0
uid_timestamp: "uid_0_ 20161207113010"
-Yi9sjmsospkos
dining_timestamp: "20161207173000"
Y79joa90ksss: true
Yjs9990kokod: true
user: uid_1
uid_timestamp: "uid_1_ 20161207173000"
然后用餐
meal
-Y79joa90ksss
name: "Pizza"
calories: "400"
barcode: "008481816164"
-Yjs9990kokod
name: "Burger"
calories: "520"
barcode: "991994411815"
以及用户可以选择的膳食
All dining for all users by date or range of dates.
All dining that contain a certain meal
All meals by a user
->The cool one<- all dining for a specific user within a date range.
如您所见,用餐节点包含每个用户的用餐活动(因此所有用餐活动都在一个节点中)
这使您可以查询各种事物:
setInterval(function() {
var token = $window.localStorage.getItem('token');
self.parseJwt = function(token) {
var base64Url = token.split('.')[1];
var base64 = base64Url.replace('-', '+').replace('_', '/');
return JSON.parse($window.atob(base64));
}
var expireTime = self.parseJwt(token);
var timeStamp = Math.floor(Date.now() / 1000);
var timeCheck = expireTime.exp - timeStamp;
//Set to expire after 15 seconds
if (timeCheck < 86385) {
console.log('time expired');
} else {
console.log('time not expired');
}
}, 3000);
一个遗漏是寻找包含两餐的餐饮,但是,解决方案也是在这个答案中。
总而言之,你的结构很健全 - 只需要稍微调整一下。