Skip to content Skip to sidebar Skip to footer

React-native-gifted-chat With Cloud Firestore Pagination

I'm using Firestore to store messages. In order to optimize the mobile application performances, I would like to set a limit(50) in the firestore query. It works well and implement

Solution 1:

Your query is OK for the first time, for consequent queries you must use the ::startAt or ::startAfter methods.

You can find more information in the official documentation. https://firebase.google.com/docs/firestore/query-data/query-cursors

Solution 2:

I am using FlatList in react-native to render chats and I had to paginate the chats list. Since Firestore query cursor is not supported in live listener, I created two list, recentChats & oldChats.

I populate recentChats using live listener query.onSnapshot & oldChats using cursor startAfter. FlatList data is combination of both list and I take care of merging logic.

constMESSAGE_LIMIT = 15;

constChatWindow = props => {
  const { sessionId, postMessage, onSendTemplateButtonPress } = props;

  // Firestore cursor is not supported in query.onSnapshot so maintaining two chat list// oldChats -> chat list via cursor, recentChats -> chat list via live listenerconst [oldChats, setOldChats] = useState([]);
  const [recentChats, setRecentChats] = useState([]);

  // if true, show a loader at the top of chat listconst [moreChatsAvailable, setMoreChatsAvailable] = useState(true);

  const [inputMessage, setInputMessage] = useState('');

  useEffect(() => {
    const query = getGuestChatMessagesQuery(sessionId)
      .limit(MESSAGE_LIMIT);
    const listener = query.onSnapshot(querySnapshot => {
      let chats = [];
      querySnapshot.forEach(snapshot => {
        chats.push(snapshot.data());
      });
      // merge recentChats & chatsif (recentChats.length > 0) {
        const newRecentChats = [];
        for (let i = 0; i < chats.length; i++) {
          if (chats[i].sessionId === recentChats[0].sessionId) {
            break;
          }
          newRecentChats.push(chats[i]);
        }
        setRecentChats([...newRecentChats, ...recentChats]);
      } else {
        setRecentChats(chats);
        if (chats.length < MESSAGE_LIMIT) {
          setMoreChatsAvailable(false);
        }
      }
    });

    return() => {
      // unsubscribe listenerlistener();
    };
  }, []);

  constonMessageInputChange = text => {
    setInputMessage(text);
  };

  constonMessageSubmit = () => {
    postMessage(inputMessage);
    setInputMessage('');
  };

  constrenderFlatListItem = ({ item }) => {
    return (<ChatBubblechat={item} />);
  };

  constonChatListEndReached = () => {
    if (!moreChatsAvailable) {
      return;
    }
    let startAfterTime;
    if (oldChats.length > 0) {
      startAfterTime = oldChats[oldChats.length - 1].time;
    } elseif (recentChats.length > 0) {
      startAfterTime = recentChats[recentChats.length - 1].time;
    } else {
      setMoreChatsAvailable(false);
      return;
    }
    // query data using cursorgetGuestChatMessagesQuery(sessionId)
      .startAfter(startAfterTime)
      .limit(MESSAGE_LIMIT)
      .get()
      .then(querySnapshot => {
        let chats = [];
        querySnapshot.forEach(snapshot => {
          chats.push(snapshot.data());
        });
        if (chats.length === 0) {
          setMoreChatsAvailable(false);
        } else {
          setOldChats([...oldChats, ...chats]);
        }
      });
  };

  return (
    <Viewstyle={[GenericStyles.fill,GenericStyles.p16]}><FlatListinverteddata={[...recentChats,...oldChats]}
        renderItem={renderFlatListItem}keyExtractor={item => item.messageId}
        onEndReached={onChatListEndReached}
        onEndReachedThreshold={0.2}
        ListFooterComponent={moreChatsAvailable ? <ActivityIndicator /> : null}
      />
      {
        Singleton.isStaff ?
          null:
          <ChatInputonMessageInputChange={onMessageInputChange}onMessageSubmit={onMessageSubmit}inputMessage={inputMessage}style={GenericStyles.selfEnd}onSendTemplateButtonPress={onSendTemplateButtonPress}
          />
      }
    </View>
  );
};

Post a Comment for "React-native-gifted-chat With Cloud Firestore Pagination"