在React Native Firebase中重新加载应用后无法更新状态吗?

时间:2019-04-28 13:34:55

标签: javascript reactjs firebase react-native firebase-realtime-database

React Native中的Firebase有一些问题。

我试图从实时数据库中读取数据。 我从数据库获取数据并将其设置为状态,而我的初始状态为空,就像这样

this.state = {
   providers: []
}

所以现在当我在控制台中记录状态时,我会很好地看到所有数据,

First Time

但是当我返回主屏幕或重新加载应用程序然后返回到同一屏幕时,在状态 Provider 中我看不到任何更新,并且控制台很清楚,这意味着Array是Func

这意味着什么!我认为代码正确吗?

这是我的代码:

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;

1 个答案:

答案 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(...),而不是在处理每一项之后。