[英]Can't update state after reloading the app in react native firebase?
I have some issues with Firebase in React Native.我对 React Native 中的 Firebase 有一些问题。
I'm tried to read the data from the Realtime database.我试图从实时数据库中读取数据。 I get the data from database and set them into the state and my initial state is empty, like this我从数据库中获取数据并将它们设置为状态,我的初始状态为空,就像这样
this.state = {
providers: []
}
So now when I log the state in the console I see all of the data very well,所以现在当我在控制台中记录状态时,我可以很好地看到所有数据,
but when I go back to Home screen or reloading app then returns to the same screen I can't see any update in the state Provider and the console is clear that's mean the Array is empty ,但是当我返回主屏幕或重新加载应用程序然后返回到同一屏幕时,我看不到状态Provider中的任何更新,并且控制台很清楚,这意味着 Array 为空,
so what this does mean!所以这是什么意思! I think the code is right?我认为代码是对的?
Here is my Code:这是我的代码:
import React, { Component } from 'react';
import MapView, { Marker } from 'react-native-maps';
import firebase from "react-native-firebase";
// import * as turf from '@turf/turf';
import * as turf from "@turf/turf";
import { View, Text, StyleSheet, Dimensions, PermissionsAndroid, Image } from 'react-native';
let { width, height } = Dimensions.get('window');
const LATITUDE = 50.78825;
const LONGITUDE = 40.4324;
const LATITUDE_DELTA = 0.0922;
const LONGITUDE_DELTA = 0.0421;
class Map extends Component {
constructor(props) {
super(props);
this.state = {
nearest: [],
currentUser: null,
error: null,
width: width,
marginBottom: 1,
region: {
longitude: LONGITUDE,
latitude: LATITUDE,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
},
providers: [],
providerObj: [],
distance: null,
};
}
componentDidMount = () => {
this.requestLocationPermission();
this.handleProvider();
};
// Get All Provider in Db
handleProvider = () => {
console.log("The function is called but can't retrieve the data!");
const providerRef = firebase.database().ref('providers');
providerRef.once('value').then(snapshot => {
// console.log(snapshot.val());
console.log("TEST!!")
let newState = [];
snapshot.forEach(async (childSnapshot) => {
console.log("The function is the data!");
await newState.push({
id: childSnapshot.val().id,
username: childSnapshot.val().username,
coordinates: {
longitude: childSnapshot.val().coordinates.longitude,
latitude: childSnapshot.val().coordinates.latitude,
}
});
});
this.setState({ providers: newState }, () => { this.handleNearby() })
});
}
// first one of nearest provider
handleNearby = () => {
const { region, providers } = this.state;
let points = providers.map(p => turf.point([p.coordinates.longitude, p.coordinates.latitude]));
let collection = turf.featureCollection(points);
let currentPoint = turf.point([region.longitude, region.latitude]);
let nearestPoint = turf.nearestPoint(currentPoint, collection);
// let addToMap = [currentPoint, points, nearestPoint];
this.setState({ nearest: nearestPoint }, () => console.log(this.state.nearest));
// console.log(Math.floor(nearest.properties.distanceToPoint));
// console.log(addToMap);
}
// Get User Location
requestLocationPermission = async () => {
const LocationPermission = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
// , {
// 'title': 'Location Access Required',
// 'message': 'This App needs to Access your location'
// }
)
if (LocationPermission === PermissionsAndroid.RESULTS.GRANTED) {
//To Check, If Permission is granted
await navigator.geolocation.getCurrentPosition(
//Will give you the current location
position => {
const longitude = position.coords.longitude;
const latitude = position.coords.latitude;
this.setState({
...this.state.region,
region: {
longitude,
latitude,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
}
},
() => {
this.handleCurrentUserLocation();
// this.handleProvider();
}
);
},
error => console.log(error.message),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
);
this.watchID = navigator.geolocation.watchPosition(position => {
//Will give you the location on location change
// console.log(position);
//getting the Longitude from the location
const longitude = position.coords.longitude;
//getting the Latitude from the location
const latitude = position.coords.latitude;
//Setting state Latitude & Longitude to re re-render the Longitude Text
// this.setState({
// region: {
// latitude,
// longitude,
// latitudeDelta: LATITUDE_DELTA,
// longitudeDelta: LONGITUDE_DELTA,
// }
this.setState({
...this.state.region,
region: {
longitude,
latitude,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
}
}, () => this.handleCurrentUserLocation());
});
}
}
// Save own Location in database
handleCurrentUserLocation = () => {
const { region } = this.state;
const currentUser = firebase.auth().currentUser;
this.setState({ currentUser });
firebase.database().ref("users/" + currentUser.uid).update({
location: {
longitude: region.longitude,
latitude: region.latitude,
}
});
}
render() {
// console.log(this.state.nearest.geometry.coordinates)
const { region, providers } = this.state;
return (
<View style={styles.container} >
<MapView
style={[styles.map, { width: this.state.width }]}
style={StyleSheet.absoluteFill}
// onMapReady={() => console.log(this.state.region)}
showsUserLocation={true}
region={region}
loadingEnabled={true}
// style={StyleSheet.absoluteFill}
textStyle={{ color: '#bc8b00' }}
containerStyle={{ backgroundColor: 'white', borderColor: '#BC8B00' }}
>
<Marker
coordinate={region}
title="Hello"
description="description"
pinColor="navy"
// onPress={() => alert("Provider Profile")}
// icon={require('../assets/camera-icon.png')}
onCalloutPress={() => alert("Provider Profile")}
/>
{this.state.providers.map((marker, index) => (<Marker key={index} coordinate={marker.coordinates} title={marker.username} />))}
{/* {this.state.nearest.map((marker, index) => (<Marker key={index} coordinate={marker.coordinates} title="f" />))} */}
</MapView>
{/* <Text>{this.state.region.latitude}</Text> */}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'space-between',
padding: 30,
flex: 1,
alignItems: 'center'
},
map: {
position: 'absolute',
zIndex: -1,
top: 0,
left: 0,
right: 0,
bottom: 0,
},
});
export default Map;
I think your database listener should look more like this:我认为您的数据库侦听器应该更像这样:
const providerRef = firebase.database().ref('providers');
providerRef.on('value', snapshot => {
var newState = [];
console.log(snapshot.val());
snapshot.forEach((childSnapshot) => {
newState.push({
id: childSnapshot.val().id,
username: childSnapshot.val().username,
coordinates: {
longitude: childSnapshot.val().coordinates.longitude,
latitude: childSnapshot.val().coordinates.latitude,
}
});
});
this.setState({ providers: newState })
});
Changes from yours:你的变化:
newState
inside the callback, so that you start out with an empty array each time you get data from Firebase.声明newState
回调里面,让你开始与空数组每次从火力地堡获取数据的时间。setState(...)
only after processing all data from the database, instead of after each item.仅在处理完数据库中的所有数据后调用setState(...)
,而不是在每个项目之后调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.