Итак, я прошел через это. Брайан помог мне в этом, поэтому я проголосовал за его ответ, но я выкладываю полный ответ здесь, чтобы другие могли получить пользу. Я пытался сохранить первоначальный вопрос как можно более сложным, но я понимаю, что это сложно, и, возможно, это не лучший форум, но я не мог найти ответ где-либо еще, и у меня был конкретный вариант использования, которым я теперь могу поделиться с код.
Вариант использования для суммирования. У меня есть предметы, хранящиеся в базе огня. Пользователь собирается выбирать из пунктов. Мне нужно хранить то, что они выбирают, но сохранять данные как можно более удобными. Брайан предложил хранить только тот ключ, который в порядке. Но я отображал то, что пользователь выбрал в элементе div в пользовательском интерфейсе, поэтому, по существу, если бы я не сохранял данные в своем профиле, мне нужно было бы фильтровать данные оригинальных элементов (я понял это после публикации Брайана), основываясь на сохраненных ключах. в моем профиле пользователя.
Я - приложение React, поэтому я подключил Реселект и использовал селекторы, чтобы загрузить 2 части данных, в которых у меня были совпадения, с фильтрами и связал их через избыточность в компонентах.
Если вы новичок в селекторах, это видео было очень полезно для меня, и это решение было подключено.
https://www.youtube.com/watch?v=XCQ0ZSr-a2o
Соответствующий код для селектора здесь. В основном вы берете список элементов и список userSelectedItems (который является просто ключами / идентификаторами) и сравниваете их. Если они совпадают, то фильтр будет иметь значение 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, поскольку все данные хранятся в элементах, а не дублируются в профилях пользователей. Спасибо Неизменным и Переселект в Реакте. Они созданы для этого материала. Надеюсь, что это помогает кому-то еще. Поймите, что сначала это было немного широко для стека, надеюсь, код поможет уточнить вариант использования и сделать его ценным для других сейчас.
И в последний раз. Мои данные теперь выглядят так в Firebase.
Пункты
-items
--id1
theData
--id2
theData
--id3
theData
--id4
theData
UserProfile
-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"
Мои высокоуровневые функции БД всегда создают новые уникальные ключи в firebase. Я не хотел менять это только для этого решения. Это работает, и все работает одинаково для CRUD в моем приложении.