React Native中的Firebase有一些问题。
我试图从实时数据库中读取数据。 我从数据库获取数据并将其设置为状态,而我的初始状态为空,就像这样
this.state = {
providers: []
}
所以现在当我在控制台中记录状态时,我会很好地看到所有数据,
但是当我返回主屏幕或重新加载应用程序然后返回到同一屏幕时,在状态 Provider 中我看不到任何更新,并且控制台很清楚,这意味着Array是空,
这意味着什么!我认为代码正确吗?
这是我的代码:
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;
答案 0 :(得分:1)
我认为您的数据库侦听器应如下所示:
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 })
});
您的更改
newState
,以便每次从Firebase获取数据时都从一个空数组开始。setState(...)
,而不是在处理每一项之后。