Listview 列出geofire区域内firebase中的元素
我试图显示一个在当前位置地理半径范围内的商户列表。我遇到的问题是,数据源似乎没有填充任何行Listview 列出geofire区域内firebase中的元素,listview,firebase,react-native,geofire,Listview,Firebase,React Native,Geofire,我试图显示一个在当前位置地理半径范围内的商户列表。我遇到的问题是,数据源似乎没有填充任何行 import React from 'react' import { View, ListView, Image, Text, ActivityIndicator } from 'react-native' import ParallaxScrollView from 'react-native-parallax-scroll-view' import AlertMessage from '../Comp
import React from 'react'
import { View, ListView, Image, Text, ActivityIndicator } from 'react-native'
import ParallaxScrollView from 'react-native-parallax-scroll-view'
import AlertMessage from '../Components/AlertMessage'
import Geocoder from 'react-native-geocoder'
import { Colors } from '../Themes/'
import { connect } from 'react-redux'
import MerchantRow from '../Components/MerchantRow'
import { firebaseApp } from '../Config/AppConfig'
const GeoFire = require('geofire')
// Styles
import styles from './Styles/MerchantListStyle'
class MerchantList extends React.Component {
watchID: ?number = null;
constructor (props) {
super(props)
this.state = {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2
}),
result: '',
city: 'you'
}
// Get references to several nodes we will need
rootRef = firebaseApp.database().ref();
merchantsRef = rootRef.child('merchants');
geofireRef = rootRef.child('locations');
this.geoFire = new GeoFire(geofireRef)
}
componentDidMount () {
navigator.geolocation.getCurrentPosition(
(position) => {
},
(error) => alert(JSON.stringify(error)),
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
)
this.watchID = navigator.geolocation.watchPosition((position) => {
var lat = position.coords.latitude;
var lng = position.coords.longitude;
Geocoder.fallbackToGoogle('AIzaSyCPVaJK7Sx-Uv6X76508NUlrpF3YJBqgrk')
let ret = Geocoder.geocodePosition({lat, lng}).then((res)=>
{
city = res['0'].locality
this.setState({ city: city })
})
let radius = 40 // 40km
let currentLocation = [
position.coords.latitude,
position.coords.longitude
]
let geoQuery = this.geoFire.query({center: currentLocation, radius})
var merchants = [];
// For every key which matches our GeoQuery...
geoQuery.on('key_entered', function(key) {
// ... look up the merchant data for that key ...
// console.log(key)
merchantsRef.child(key).once('value').then(function(snapshot) {
// ... and add it to the matches array
merchants.push(snapshot.val())
console.log(merchants)
this.setState({
loading: false,
dataSource: this.state.dataSource.cloneWithRows(merchants)
})
}).catch(function(error) {
console.log('Error fetching merchant data:', error)
})
})
})
}
componentWillUnmount () {
navigator.geolocation.clearWatch(this.watchID)
}
_renderRow (item) {
return (
<MerchantRow data={item} />
)
}
_noRowData () {
return this.state.dataSource.getRowCount() === 0
}
render () {
return (
<View style={styles.container}>
<ListView
dataSource={this.state.dataSource}
renderRow={this._renderRow.bind(this)}
enableEmptySections
pageSize={15}
renderScrollComponent={props => (
<ParallaxScrollView
backgroundColor={Colors.background}
contentBackgroundColor={Colors.background}
parallaxHeaderHeight={250}
renderBackground={() => (
<Image
style={styles.photo}
source={{uri: this.props.photo}}
defaultSource={require('../Images/Merchant_Header.png')}
/>
)}
renderForeground={() => (
<View key='parallax-header' style={styles.parallaxHeader}>
<Text style={styles.title}>
{'Choose a café near\n' + this.state.city + ' to start\n your order'}
</Text>
</View>
)}
/>
)}
/>
<AlertMessage title='Nothing to See Here, Move Along' show={this._noRowData()} />
</View>
)
}
}
const mapStateToProps = (state) => {
return {
// ...redux state to props here
}
}
const mapDispatchToProps = (dispatch) => {
return {
}
}
export default connect(mapStateToProps, mapDispatchToProps)(MerchantList)
从“React”导入React
从“react native”导入{View、ListView、图像、文本、ActivityIndicator}
从“反应本机视差滚动视图”导入视差滚动视图
从“../Components/AlertMessage”导入AlertMessage
从“react native Geocoder”导入地理编码器
从“../Themes/”导入{Colors}
从“react redux”导入{connect}
从“../Components/MerchantRow”导入MerchantRow
从“../Config/AppConfig”导入{firebaseApp}
const GeoFire=require('GeoFire')
//风格
从“./styles/MerchantListStyle”导入样式
类MerchantList扩展了React.Component{
watchID:?number=null;
建造师(道具){
超级(道具)
此.state={
数据源:新建ListView.dataSource({
行已更改:(行1,行2)=>行1!==行2
}),
结果:“”,
城市:你
}
//获取我们需要的几个节点的引用
rootRef=firebaseApp.database().ref();
merchantsRef=rootRef.child('merchants');
geofireRef=rootRef.child('locations');
this.geoFire=新的geoFire(geofireRef)
}
组件安装(){
navigator.geolocation.getCurrentPosition(
(职位)=>{
},
(错误)=>警报(JSON.stringify(错误)),
{enableHighAccurance:true,超时:20000,最大值:1000}
)
this.watchID=navigator.geolocation.watchPosition((位置)=>{
var lat=位置坐标纬度;
var lng=位置坐标经度;
地理编码器。回退到日志('AIzaSyCPVaJK7Sx-Uv6X76508NUlrpF3YJBqgrk')
让ret=Geocoder.geocodePosition({lat,lng})。然后((res)=>
{
城市=res['0']。地点
this.setState({city:city})
})
让半径=40//40km
让currentLocation=[
位置坐标纬度,
位置坐标经度
]
让geoQuery=this.geoFire.query({center:currentLocation,radius})
var=[];
//对于与我们的地理查询匹配的每个键。。。
geoQuery.on('key_entered',函数(key){
//…查找该密钥的商户数据。。。
//console.log(键)
merchantsRef.child(键)。一次('value')。然后(函数(快照){
//…并将其添加到matches数组中
bunchers.push(snapshot.val())
控制台日志(商户)
这是我的国家({
加载:false,
dataSource:this.state.dataSource.cloneWithRows(商户)
})
}).catch(函数(错误){
console.log('获取商户数据时出错:',错误)
})
})
})
}
组件将卸载(){
navigator.geolocation.clearWatch(this.watchID)
}
_渲染箭头(项目){
返回(
)
}
_noRowData(){
返回此.state.dataSource.getRowCount()==0
}
渲染(){
返回(
(
(
)}
renderForeground={()=>(
{'Choose a cafénear\n'+this.state.city+'开始\n您的订单'}
)}
/>
)}
/>
)
}
}
常量mapStateToProps=(状态)=>{
返回{
//…将状态重新复制到这里的道具
}
}
const mapDispatchToProps=(调度)=>{
返回{
}
}
导出默认连接(MapStateTrops、mapDispatchToProps)(商品列表)
出现问题的原因是您使用的是普通回调函数,而不是使用使用fat箭头的ES6函数
geoQuery.on('key_entered', function(key) {
// ... look up the merchant data for that key ...
// console.log(key)
merchantsRef.child(key).once('value').then(function(snapshot) {
// ... and add it to the matches array
merchants.push(snapshot.val())
console.log(merchants)
this.setState({
loading: false,
dataSource: this.state.dataSource.cloneWithRows(merchants)
})
}).catch(function(error) {
console.log('Error fetching merchant data:', error)
})
})
this
对象应该引用this.state.dataSource.cloneWithRows(招商局)
中的类。但是,在Javascript中,普通回调函数({}将创建并绑定自己的这个对象,而不是来自其父对象的对象,这意味着this.state.dataSource.cloneWithRows(merchants)
现在无效。为了防止这种情况,您应该使用ES6函数语法,它不进行任何绑定
更新后的代码应如下所示:
geoQuery.on('key_entered', (key) => { // Using fat arrows
// ... look up the merchant data for that key ...
// console.log(key)
merchantsRef.child(key).once('value').then((snapshot) => { // here too!
// ... and add it to the matches array
merchants.push(snapshot.val())
console.log(merchants)
this.setState({
loading: false,
dataSource: this.state.dataSource.cloneWithRows(merchants)
})
}).catch((error) => { // If you are planning to use this here
console.log('Error fetching merchant data:', error)
})
})
const that = this; // created a reference!
geoQuery.on('key_entered', function(key) {
// ... look up the merchant data for that key ...
// console.log(key)
merchantsRef.child(key).once('value').then(function(snapshot) {
// ... and add it to the matches array
merchants.push(snapshot.val())
console.log(merchants)
that.setState({ // Use the reference here!
loading: false,
dataSource: that.state.dataSource.cloneWithRows(merchants) // Here too!
})
}).catch(function(error) {
console.log('Error fetching merchant data:', error)
})
})
如果要使用普通回调函数语法而不是ES6版本,可以在函数外部创建对此的引用,并在内部使用新引用。在这种情况下,您的代码应该如下所示:
geoQuery.on('key_entered', (key) => { // Using fat arrows
// ... look up the merchant data for that key ...
// console.log(key)
merchantsRef.child(key).once('value').then((snapshot) => { // here too!
// ... and add it to the matches array
merchants.push(snapshot.val())
console.log(merchants)
this.setState({
loading: false,
dataSource: this.state.dataSource.cloneWithRows(merchants)
})
}).catch((error) => { // If you are planning to use this here
console.log('Error fetching merchant data:', error)
})
})
const that = this; // created a reference!
geoQuery.on('key_entered', function(key) {
// ... look up the merchant data for that key ...
// console.log(key)
merchantsRef.child(key).once('value').then(function(snapshot) {
// ... and add it to the matches array
merchants.push(snapshot.val())
console.log(merchants)
that.setState({ // Use the reference here!
loading: false,
dataSource: that.state.dataSource.cloneWithRows(merchants) // Here too!
})
}).catch(function(error) {
console.log('Error fetching merchant data:', error)
})
})