Чтение и отображение данных из документа Firestore в React Native

#firebase #react-native #google-cloud-firestore

#firebase #react-native #google-облако-firestore

Вопрос:

Справочная информация

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

Что мне нужно

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

Вопрос

Как можно получить данные из коллекции Firestore в react native, затем присвоить данным из каждого документа отдельную осязаемую непрозрачность (я знаю о передаче параметров с помощью react navigation, я просто не знаю, какой параметр передавать при работе с Firestore), а затем отобразить эти данные в хранилищеподробный экран?

Пример кода для контекста

App.js

     <NavigationContainer> 
  <Stack.Navigator initialRouteName={user ? 'Home' : 'Login'}
    screenOptions={{cardStyle: { backgroundColor: '#FFFFFF' }}}> 
    <Stack.Screen name="Home"options={{headerShown: false}}> 
      {props => <HomeScreen {...props} extraData={user} />} 
    </Stack.Screen> 
    <Stack.Screen name="Login" component={LoginScreen} options={{headerShown: false}}/> 
    <Stack.Screen name="Registration" component={RegistrationScreen}  options={{headerShown: false}}/> 
    <Stack.Screen name="storeDetail" options={{title: ''}}> 
        {props => <storeDetail {...props} extraData={} />} 
    </Stack.Screen> 
  </Stack.Navigator> 
</NavigationContainer>
  

В этом файле вы увидите, что я уже вызвал некоторые данные (Login и Register передают userData на главный экран), однако для реализации этого метода я зависел от ответа от метода аутентификации, который я использовал. Я полагаю, хотя мне, вероятно, нужно будет передать что-то в качестве дополнительных данных, я понимаю, что мне следует делать, я просто не знаю, как заполнить пробелы.

Заранее большое спасибо!

Ответ №1:

Во-первых, установите Firebase SDK в свое приложение, чтобы вы могли делать запросы к своей серверной части.

Я не знаю, соответствует ли ваш образец App.js представляет текущее состояние прогресса в вашем приложении, но я собираюсь предположить, что:

  • у вас уже есть созданный экран storeDetail
  • идентификатор хранилища известен до перехода к экрану (например, на главном экране)
  • вы передаете StoreID в качестве параметра навигации при переходе к storeDetail

Таким образом, на экране storeSetails вы можете запрашивать Firestore при получении storeId и сохранять результат в переменной состояния при успешном выполнении:

 
const StoreDetailsScreen = ({ route }) => { // route is passed as a prop by React Navigation
  const { storeId } = route.params
  const [store, setStore] = useState()
  const [loading, setLoading] = useState(true) // show a loading spinner instead of store data until it's available

  useEffect(() => {

    const fetchQuery = async () => {
      const storeData = await firestore()
        .collection('stores')
        .doc(storeId)
        .get() // this queries the database

        if (storeData) {
          setStore(storeData) // save the data to store state
          setLoading(false) // set loading to false 
        } else {
          // something went wrong, show an error message or something
        }
    }

    fetchQuery()

  }, [storeId])

  if (loading) {
    return (
      <ActivityIndicator/>
    )
  }
  
  return (
    // ... store details
  )

}

  

Затем вы можете использовать данные store для отображения содержимого на вашем экране

 <Text>{store.name}</Text>
<Text>{store.email}</Text>
// ...
  

Дополнительная информация о том, как использовать Firestore в RN: https://rnfirebase.io/firestore/usage

Комментарии:

1. Извините, что перезвонил вам так поздно, только сейчас я читаю ваш ответ. Это выглядит великолепно! Но я действительно не знаю, как передать идентификатор в качестве параметра. Я думаю о чем-то похожем: navigation.navigate(‘storeDetail’, IDHERE). Но как приложение узнает, откуда получить этот идентификатор? Это просто строка, на которую приложение затем ссылается при запросе к базе данных, или ему нужно получить ее откуда-то раньше? Большое спасибо!

2. Вы можете передать id в качестве параметра следующим navigation.navigate('storeDetail', { storeId: the_store_id }) образом . Подробнее здесь: reactnavigation.org/docs/params Конечно, это означает, что вы должны the_store_id каким-то образом быть доступны. Обычно у вас будет более общий запрос (например, getAllStoreIds) на предыдущем экране (рабочий стол), который будет извлекать нужные вам идентификаторы. Вы можете сохранить их в состоянии так же, как мы делаем это в ответе выше, а затем использовать содержимое этого состояния для отображения списка, где каждый элемент является ссылкой на страницу сведений.

3. Большое спасибо! Ваш ответ был отличным и помог мне разобраться во всем. Еще раз большое спасибо за столь четкое объяснение.

4. Привет, я не уверен, прочтете ли вы это, но у меня возникли небольшие проблемы с реализацией вашего решения (был занят работой над другими частями приложения, и это немного отодвинулось), я сделал все, что вы сказали, но как только я пытаюсь отобразить информацию, как в <Text>{store.name}</Text> , я получаю сообщение об ошибкевыражение undefined не является объектом. Все в моем коде именно так, как вы мне показали.

5. Кроме того, при попытке консольного журнала StoreID возвращает правильный идентификатор, но попытка консольного журнала «store» возвращает undefined.