Поиск нескольких записей Firebase с помощью действия Redux - PullRequest
0 голосов
/ 01 октября 2019

У меня есть это действие Redux, которое ищет пользователя и возвращает все элементы, которые у него есть:

export const itemsFetch = () => {
  const { currentUser } = firebase.auth();
  return dispatch => {
    firebase
      .database()
      .ref(`users/${currentUser.uid}/items`)
      .on('value', snapshot => {
        dispatch({ type: ITEMS_FETCH_SUCCESS, payload: snapshot.val() });
      });
  };
};

Отлично работает, и каждому возвращенному элементу присвоен уникальный ключ.

Я хочу изменить это действие для поиска определенных элементов , что я и сделал. Это тоже отлично работает:

export const itemLookup = uid => {
  const { currentUser } = firebase.auth();
  return dispatch => {
    firebase
      .database()
      .ref(`users/${currentUser.uid}/items/${uid}`)
      .on('value', snapshot => {
        dispatch({ type: ITEM_LOOKUP_SUCCESS, payload: snapshot.val() });
      });
  };
};

Это тоже хорошо работает, но я могу использовать это только для поиска одного элемента.

Я хочу перебрать массив идентификаторов предметов и детали поиска для каждого. Выполнение этого из компонента и использование mapStateToProps приводит к тому, что компонент каждый раз перерисовывается, теряя предыдущий поиск в процессе.

Лучше ли перебирать идентификаторы, имеющиеся у меня на уровне компонента, исделать несколько звонков. Или я должен передать массив в действие и каким-то образом зациклить их внутри действия?

Спасибо

Мне кажется, что я делаю что-то глупое или неправильно понимаю Redux.

Ответы [ 2 ]

1 голос
/ 02 октября 2019

На мой взгляд, это одно из немногих ограничений, которые есть у firebase (наряду с запросами), которые иногда заставляют меня снова захотеть отрастить волосы и потерять их (я лысый).

У меня больше опыта в Firestore, хотя я использовал базу данных, но я думаю, что вы правы, что вы можете запросить только один элемент в Firebase. Чтобы решить эту проблему, я должен создать новое действие, которое получает массив идентификаторов, а затем выполняет и массив обещаний, которые будут запрашивать каждый документ.

Что-то вроде (псевдокод, и вам может понадобиться заключить вызов Firebase в обещание):

let promises = [];
arrayIds.forEach(id => {
   promises.push(firebase.database().ref.get(id))
})
return Promise.all(promises).then(dispatch(results))

Теперь, если вы обнаружите, что количество результатов обычно не многоЭто вполне нормально (и, как обычно того требует Firebase), чтобы выполнить фильтрацию данных в клиенте.

0 голосов
/ 02 октября 2019

Используя ответ от sfratini, мне удалось это решить. Вот действие:

export const itemLookup = oid => {
  const { currentUser } = firebase.auth();

  const items = []

  return dispatch => {
    new Promise(function (res, rej) {
      oid.forEach(id => {
        firebase.database().ref(`users/${currentUser.uid}/items/${id}`).on('value', snapshot => {
          items.push(snapshot.val())
        })
      })

    }).then(dispatch({ type: ITEM_LOOKUP_SUCCESS, payload: items }))
  }

Я использовал тот же редуктор, и теперь массив items переходит на уровень компонентов. Отлично!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...