Я внедряю Infinite Scroll с Cloud Firestore и использую lastVisible в качестве ссылки на документ, чтобы узнать, где находятся запросы на обновление для еще 5 пользователей (ограничение установлено на 5).
Проблема исходит от "lastVisible" и возвращается как неопределенная в строке. Он добавляет lastVisible к массиву visibles в состоянии при запуске начальной функции «retrieveUsers», но не в функции retrieveMore.
console.log (this.state.visibles)
Visibles (Retrieve More)
Array [
Object {
"company": "Google",
"first_name": "Dan",
"last_name": "Jones",
"email": null,
"phone_number": "(553) 402-8023",
},
undefined,
]
Paginated Query starting (Retrieve More)
Проблема заключается в добавлении второго, третьего, четвертого и т. Д. Последних видимых документов в массив this.state.visibles. Он не определен, что отбрасывает мои запросы Cloud Firestore, потому что он не знает, каким был последний видимый документ.
Ошибка: «Функция Query.startAfter () требует допустимого первого аргумента, но он не определен».
// Imports: Dependencies
import React, { Component } from "react";
import { ActivityIndicator, Dimensions, FlatList, View, SafeAreaView, ScrollView, StyleSheet, Text, TouchableOpacity } from 'react-native';
import * as firebase from 'firebase';
import 'firebase/firestore';
import firebaseConfig from '../config/config';
// Imports: Components
import UserSelector from '../components/UserSelector';
import TitleLarge from '../components/TitleLarge';
// Screen Dimensions
const { height, width } = Dimensions.get('window');
// Screen: Flat List (Users)
class FlatListUsers extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
limit: 5,
visibles: [],
loading: false,
refreshing: false,
};
}
// Component Will Mount
componentWillMount = () => {
// Firebase: Initialize
firebase.initializeApp({
apiKey: `${firebaseConfig.apiKey}`,
authDomain: `${firebaseConfig.authDomain}`,
databaseURL: `${firebaseConfig.databaseURL}`,
projectId: `${firebaseConfig.projectId}`,
storageBucket: `${firebaseConfig.storageBucket}`,
messagingSenderId: `${firebaseConfig.messagingSenderId}`,
});
}
// Component Did Mount
componentDidMount = () => {
this.retrieveUsers();
}
// Retrieve Users
retrieveUsers = async () => {
try {
// Set State: Loading
this.setState({ loading: true });
// Firebase: Database + Settings
const db = firebase.firestore();
// Query
console.log('Fetching Users')
let initialQuery = await db.collection('licenses')
.where('company', '==', 'Google')
.orderBy('first_name')
.limit(5)
// Query Snapshot
let documentSnapshots = await initialQuery.get();
// Document Data
let documentData = documentSnapshots.docs.map(document => document.data());
// Last Visible Document (To Start From For Proceeding Queries)
let lastVisible = documentData[documentData.length - 1];
// Set State
this.setState({
data: [...this.state.data, ...documentData],
visibles: [...this.state.visibles, lastVisible],
loading: false,
refreshing: false,
});
console.log('Last Visible');
console.log(this.state.visibles);
}
catch (error) {
console.log(error);
}
};
// Retrieve More Users
retrieveMore = async () => {
try {
console.log('Retrieving more Users (Retrieve More)');
this.setState({ loading: true });
console.log('Visibles (Retrieve More)');
console.log(this.state.visibles);
// Firebase: Database + Settings
const db = firebase.firestore();
// Query
console.log('Paginated Query starting (Retrieve More)');
let initialQuery = await db.collection('licenses')
.where('company', '==', 'Google')
.orderBy('first_name')
.startAfter(this.state.visibles[this.state.visibles.length - 1])
.limit(5);
// Query Snapshot
let documentSnapshots = await initialQuery.get();
// Last Visible Document (To Start From For Proceeding Queries)
let lastVisible = documentSnapshots[documentSnapshots.length - 1];
console.log('Last Visible');
console.log(typeof this.state.lastVisible);
console.log(JSON.stringify(this.state.lastVisible));
// Document Data
let documentData = documentSnapshots.docs.map(document => document.data());
// Set State
this.setState({
data: [...this.state.data, ...documentData],
visibles: [...this.state.visibles, lastVisible],
loading: false,
refreshing: false,
});
}
catch (error) {
console.log(error);
}
};
// Render Header
renderHeader = () => {
try {
return (
<View style={styles.activityIndicator}>
<TitleLarge title="Users" />
</View>
)
}
catch (error) {
console.log(error);
}
};
// Render Footer
renderFooter = () => {
try {
// Check If Loading
if (this.state.loading) {
return <ActivityIndicator />
}
else {
return null;
}
}
catch (error) {
console.log(error);
}
};
render() {
return (
<SafeAreaView style={styles.container}>
<FlatList
data={this.state.data}
renderItem={({ item }) => (
<UserSelector
firstName={item.first_name}
lastName={item.last_name}
company={item.company}
/>
)}
keyExtractor={(item, index) => String(index)}
ListHeaderComponent={this.renderHeader}
ListFooterComponent={this.renderFooter}
onEndReached={()=> {
if (this.state.loading === false) {
this.retrieveMore();
}
}}
onEndReachedThreshold={0}
/>
</SafeAreaView>
)
}
}
// Styles
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
height: height,
width: width,
borderTopWidth: 0,
borderBottomWidth: 0,
},
scrollView:{
height: 'auto',
},
userContainer: {
width: width,
marginBottom: 7,
},
itemText: {
fontFamily: 'System',
fontSize: 17,
fontWeight: '400',
color: '#222222',
marginLeft: 16,
},
activityIndicator: {
paddingVertical: 20,
borderTopWidth: 0,
borderTopColor: '#CED0CE',
},
});
// Exports
export default FlatListUsers