简体   繁体   中英

Integrating Firebase Realtime Database with React Native App

I am for the first time learning about state, and followed a simple tutorial to create a react native app. The tutorial did not cover using firebase, so this is what I've pieced together. It "works", but does not pull the database data on the first render. I know it's because of the delay in time it takes to grab the data vs my app rendering. But I don't know how I should move logic around to fix it. I feel like I should be using the .then somehow? Or am I doing all of this completely wrong...

import {db} from '../../src/config.js';

let initialMessages = [];
db.ref().once('value', (snapshot) =>{
  snapshot.forEach((child)=>{
    child.forEach(function(childChildSnapshot) {
      initialMessages.push({
        id: childChildSnapshot.key,
        title: childChildSnapshot.val().title,
      })
    })
  })
})
.then()
.catch((error) => {console.error('Error:', error)});

function MessagesScreen(props) {
  const [messages, setMessages] = useState(initialMessages);
  return (
    <Screens>
      <View style={styles.wholeThing}>
         <FlatList
          data={messages}
          keyExtractor={(messages) => messages.id.toString()}
          renderItem={({ item }) => (
            <Card
              title={item.title}
              onPress={() => console.log("hi")}
            />
          )}
          ItemSeparatorComponent={ListItemSeparator}
          contentContainerStyle={styles.messagesList}
          refreshing={refreshing}
          onRefresh={}
        />
      </View>
    </Screens>
  );
}

export default MessagesScreen;

By the time you pass initialMessages to the state hook (as its initial value), the initialMessages.push(...) hasn't been called yet.

Instead, you need to call setMessages when the data has loaded:

db.ref().once('value', (snapshot) =>{
  snapshot.forEach((child)=>{
    child.forEach(function(childChildSnapshot) {
      initialMessages.push({
        id: childChildSnapshot.key,
        title: childChildSnapshot.val().title,
      })
    })
    setMessages(initialMessages);
  })
})

Calling setMessages will then rerender the (affected) UI, and that will show the messages.

This of course means that you'll need to pull the useState hook out of MessagesScreen , so that it's also visible in the location where you now call setMessages .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM