Firebase数据库关系问题-为用户存储所选项目



所以我绝对是一个firebase,在这一点上只是一个noSql noob。这是我的问题。

我有一组这样的数据

-items
--id1
theData
--id2
theData
--id3
theData
--id4
theData      

我有一些用户将选择此数据的子集。示例用户A和用户B现在。

-itemSelected
---UserA
---Id1  (different than item key)
theData from items id1 (with items id1 key included so I can reference)
---Id2  (different than item key)
theData from items id3 (with items id3 key included so I can  reference)
---UserB
---Id1 (different than item key)
theData from items id1 (with items id1 key included so I can reference)
---Id2 (different than item key)
theData from items id4 (with items id4 key included so I can reference)

有了一个更加结构化规范化的SQL背景,我觉得我错了。随着我的发展,我看到如果我更改项目数据,那么我的用户数据文档中会有坏数据。到目前为止,我的项目进展顺利,并不是一个大项目。我想用firebase实时数据库来完成它,我想了解一下这个noSql。那么,在如何设置这一点上,我遗漏了什么或做错了什么。或者我应该换成Firestore吗?如果是,那该如何解决我的问题。

仅供参考-我需要参考的原因是,有时需要比较这两条数据,以便正确显示表格。我认为密钥是比较数据的自然方式。再说一次,我可能对SQL很有头脑。

希望有一些noSql或firebase专家来提供一些解决方案。谢谢

更新

基于响应者Bryan Massoth,我认为这是有目的的新结构。

-items
--id1
theData
--id2
theData
--id3
theData
--id4
theData      

我有一些用户会选择这个数据的子集,但不存储数据的副本,只存储项目ID的键值和所选的布尔值true。示例用户A和用户B现在。

-itemSelected
---UserA
---Id1  (different than item key)
id1KeyFromItems: "True"
---Id2  (different than item key)
id3KeyFromItems: "True"
---UserB
---Id1 (different than item key)
id1KeyFromItems: "True"
---Id2 (different than item key)
id4KeyFromItems: "True"

因此,我可能看到的最后一个问题是,我目前正在另一个表中显示用户选择的数据,这就是为什么我最初在firebase中将所有子选择的数据写入用户A或用户B的配置文件。所以我可以很容易地订阅它并从那里显示它。如果我走布尔路线,如果我只存储密钥,我如何只显示用户A选择的项目的数据?

很多结构都取决于您将如何使用数据。我认为你的大部分结构都是正确的。我要做的唯一区别是不复制itemSelected/{userId}下的数据。如果选择了实际itemId,则将其设置为true

-itemSelected
-UserA
-Id1 (same as items Id1): true
-Id2 (same as items Id2): true

这会增加额外的负载,但通过良好的UI/UX设计可以隐藏这些负载。这将允许搜索已选择特定项目的用户。它还将确保数据不会坏。

关于存储在itemSelected中的数据的"子集"注释:如果您指的是特定项目的数据是items表中为该项目存储的数据的子集,并且是为安全性而设计的(即items部分中的一些数据不应被用户看到),那么我建议保持一切不变,但只创建一个Firebase函数来"最终"保持记录的一致性。

所以我已经经历了这些。布莱恩让我走了一段路,所以我对他的回应投了赞成票,但我在这里发布了完整的答案,这样其他人可能会受益。我尽量把最初的问题简单化,但我意识到这很难,这可能不是最好的论坛,但我在其他地方找不到答案,我有具体的用例,我现在可以用代码分享更多。

使用案例进行汇总。我有物品存放在防火区。用户将从项目中进行选择。我需要存储他们选择的内容,但尽可能保持数据的可维护性。Bryan建议只保存好钥匙。但我在UI的div中显示了用户选择的内容,所以本质上,如果我不将数据存储在那里的配置文件中,我需要根据我的用户配置文件中存储的密钥过滤原始项目数据(我在bryan的帖子后意识到了这一点)。

我是一个React应用程序,所以我连接了Reselect,并使用Selectors加载了我与过滤器匹配的2个数据部分,并通过组件中的redux将它们连接起来。

如果你是选择器的新手,这个视频对我和连接这个解决方案很有帮助。

https://www.youtube.com/watch?v=XCQ0ZSr-a2o

此处为选择器的相关代码。基本上,您可以获取项目列表和userSelectedItems列表(这只是密钥/ids)并进行比较。若它们相同,那个么过滤器将为新的过滤列表评估true。

这是我挑选的东西。

export function getUser(state) {
return state.User;
}
export function getUserItemsList(state) {
return getTeam(state).list;
}

export function getItemsList(state) {
return state.Items.list
}
export function getUserItemsFilter(userItems, items) {
const selectedItems = items.filter(
item => userItems.some(userItem => userItem.itemKey === item.key));
return selectedItems
}
export const ItemSelector = createSelector(
getUserItemsList,  //pick off piece of state
getItemsList,  //pick off piece of state
getUserItemsFilter //last argument that runs for Item Selector, do processing here
);

回到你创建的导入选择器的组件中,并像这样将其连接到你的mapStateToProps。

const mapStateToProps = state => {
return {
itemsSelected: ItemSelector(state),
}
}

const mapDispatchToProps = Object.assign(
{},
userActions,
);
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(UserPage));

现在,ItemsSelected将被映射到React组件的状态。它是一个筛选的Items数组,其中只有与您存储在用户配置文件中的值条目具有相同键的值条目。

这确实解决了我最初在Firebase中更容易维护数据的问题,因为所有数据都在项目中,而不是在用户配置文件中重复。感谢Immutable和React中的重新选择。它们是为这些东西而建的。希望这能帮助其他人。首先要意识到这对栈来说有点宽泛,希望代码能帮助完善用例,并使其对其他人有价值。

最后一次。我的数据现在在firebase中是这样的。

项目

-items
--id1
theData
--id2
theData
--id3
theData
--id4
theData      

用户档案

-itemSelected
---UserA
---Id1  (different than item key)
"id": "id1KeyFromItems"
---Id2  (different than item key)
"id": "id3KeyFromItems"
---UserB
---Id1 (different than item key)
"id": "id1KeyFromItems"
---Id2 (different than item key)
"id": "id4KeyFromItems"

我的高级DB函数总是在firebase中创建新的唯一密钥。我不想仅仅为了这个解决方案而改变它。这样可以让我的应用程序中的CRUD保持一切正常运行。

最新更新