Error when using geolocation react-native - geolocation

I'm using geolocation but i get the error: "undefined is not an object(evaluating 'navigator.geolocation.getCurrentPosition')
According to documentation, it's not necessary import Geolocation using react native 0.60 version or above.
version:
react-native-cli: 2.0.1
react-native: 0.60.4
import React, { Component } from "react";
import {
StyleSheet,
Text,
View,
Alert,
TouchableOpacity
} from "react-native";
export default class App extends Component {
state = {
location: null
};
findCoordinates = () => {
navigator.geolocation.getCurrentPosition(
position => {
const location = JSON.stringify(position);
this.setState({ location });
},
error => Alert.alert(error.message),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 }
);
};
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.findCoordinates}>
<Text style={styles.text}>Find My Coords?</Text>
<Text>Location: {this.state.location}</Text>
</TouchableOpacity>
</View>
);
}
}

i faced the same problem and i think that from 0.60 and above navigator it isn't supported so you have to use Geolocation

Related

React Native NOT rendering data from database on IOS

I have problem with render data on IOS Simulator. Render is work properly on website, but on IOS I still got stuck on "Loading.." text.
Here is my code:
import React from 'react'
import { useState } from 'react';
import { useEffect } from 'react';
import { SafeAreaView, Text, View, StyleSheet, Image, Alert } from 'react-native';
import { Card } from 'react-native-paper'
import firebase from 'firebase'
import Button from '../components/Button'
import Background from '../components/Background'
import TopBar from '../components/TopBar'
export default function HomeScreen({ navigation }) {
const [data, setData] = useState([])
const sampleData = [{id:0, title:"One"}, {id:1, title: "Two"}]
useEffect(() =>
{
const donorsData = [];
firebase.database()
.ref("testdb")
.orderByChild("isDonor")
.equalTo(true)
.once("value")
.then((results) => {
results.forEach((snapshot) => {
donorsData.push(snapshot.val());
});
setData(donorsData);
});
}, [])
const card = data.length > 0
? data.map(item =>
{
return <Card key={item.uid} style={{ marginBottom: 20, borderRadius: 10, }}>
<Text>{item.name}</Text>
<Text>{item.description}</Text>
<Image src={item.photo}></Image>
</Card>
})
: <Text>Loading...</Text>
return (
<View style={styles.container}>
{card}
</View>
);
}
On website is everything ok Website Screen
But on IOS Simulator I got only Loading
IOS Screen
I tried a lot of solutions found here, but no one works with this case. I think is probably because iOS doesn't have data? When I put console log at to top of return, I got nothing.
This might be a race condition error. You shouldn't rely on the data being fetched within 1500ms.
If that doesn't work. Make sure your result from firebase is correct.
Maybe something like this?
const [data, setData] = useState([])
const fetchDonorData = () => {
firebase.database()
.ref("testdb")
.orderByChild("isDonor")
.equalTo(true)
.once("value")
.then((results) => {
console.log({result}) //Make sure the data looks the way you want it
const mappedResult = results?.map(snapshot => snapshot.val())
setData(mappedResult)
})
}
useEffect(() => {
fetchDonorData()
}, [])
const renderItem = ({item}) =>
<Card style={{ marginBottom: 20, borderRadius: 10, }}>
<Text>{item.name}</Text>
<Text>{item.description}</Text>
<Image src={item.photo}></Image>
</Card>
return (
<View style={styles.container}>
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={({item}) => item.uid}
ListEmptyComponent={<Text>Loading...</Text>}
/>
</View>
)

Why does my react native app not update state on ios device?

I'm trying to show an icon when my app makes a request to the backend. But sometimes the icon does not disappear.
I have the following code:
const [spinner, setSpinner] = useState(false);
useEffect(() => {
_fetchForm();
}, []);
async function _fetchForm () {
try {
setSpinner(true);
const form = await api.fetchCreateForm();
dispatch(swotsActions.setSwotsForm(form));
setSpinner(false);
} catch {
setSpinner(false);
}
}
if (!spinner) {
return <Form/>;
} else {
return <Spinner/>;
}
The Spinner component:
import React from 'react';
import { ActivityIndicator, Modal, StyleSheet, View } from 'react-native';
import { colors } from 'utilities/styles';
export default function Spinner () {
return (
<Modal
onRequestClose={() => {}}
transparent={true}
visible={true}
>
<View style={styles.wrapper}>
<ActivityIndicator
animating={true}
color={colors.black}
size='large'
/>
</View>
</Modal>
);
}
And only on ios devices sometimes both components appear
I using expo sdk 44, the same code works on skd 42 (which will be deprecated soon)

Unable to Trigger React Navigation from React Native Maps

I'm building a react native app using the react-native-maps dependency but am unable to navigate to other screens using react-navigator onPress from within the MapView.
I would like to pass the { communityId: ${community._id} } object to view the unique community screen.
code:
import React, { Component } from 'react';
import { View, Image, StyleSheet, Vibration, TouchableOpacity, Text } from 'react-native';
import MapView, { Callout } from 'react-native-maps';
import { Marker } from 'react-native-maps';
class LogoTitle extends React.Component {
render() {
return (
<Image
source={require("./logo.png")}
style={{ width: 60, height: 30 }}
/>
);
}
}
class MapScreen extends Component {
constructor(props) {
super(props);
this.state = {
latitude: null,
longitude: null,
error: null,
communities: ""
};
}
componentDidMount() {
fetch("http://localhost:4000/community")
.then(res => res.json())
.then(res => {
this.setState({ communities: res });
});
Vibration.vibrate();
navigator.geolocation.getCurrentPosition(
(position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
error: null,
});
},
(error) => this.setState({ error: error.message }),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 },
);
}
static navigationOptions = {
headerTitle: <LogoTitle />
};
navigateToView(viewName, { param: value }) {
console.log(viewName);
const { navigate } = this.props.navigation;
navigate(viewName, { param: value });
}
render() {
const LatLng = {
latitude: this.state.latitude,
longitude: this.state.longitude
}
let commcoords;
this.state.communities &&
(commcoords = this.state.communities.map((community, id) => {
let commlatlong;
commlatlong = {
latitude: community.location.lat,
longitude: community.location.long
};
return (
<Marker
key={id}
coordinate={commlatlong}
title={community.name}>
<Callout>
<TouchableOpacity
onPress={() => this.navigateToView("Community", { communityId: `${community._id}` })}
style={styles.communityButton}>
<Text style={styles.communityButtonText}>{community.name}</Text>
<Text style={styles.descButtonText}>{community.description}</Text>
</TouchableOpacity>
</Callout>
</Marker>
)
}))
return (
<View style={styles.container}>
{this.state.latitude &&
<MapView
style={styles.map}
initialRegion={{
latitude: this.state.latitude,
longitude: this.state.longitude,
latitudeDelta: 0.1011,
longitudeDelta: 0.1011,
}}>
<Marker
coordinate={LatLng}
title={`Latitude: ${this.state.latitude}`}
description={`Longitude: ${this.state.longitude}`}
pinColor='#000000'>
</Marker>
{commcoords}
</MapView>}
</View>
);
}
}
I have already attempted:
1) Using the normal navigation method.
onPress={() => this.props.navigation.navigate("Community", { communityId: `${community._id}` })}
2) Using alternate touch methods, buttons, touchable highlights, etc.
3) Attempted to console.log the triggered touch method using the remote debugger. The console.log was never triggered in the console.
navigateToView(viewName, { param: value }) {
console.log(viewName);
const { navigate } = this.props.navigation;
navigate(viewName, { param: value });
}
4) Researched and attempted solutions to no avail from the following stackoverflow links:
React Native - How to use React Navigation with React Native Maps?
React native maps click pin to take you to another screen
I would like to resolve this maps navigation issue to increase functionality in this native app. If there is an alternative method, I am open to any and all suggestions. Thank you.
I figured out how to trigger an the onpress event by using onCalloutPress in the Marker:
<Marker
key={id}
coordinate={commlatlong}
title={community.name}
onCalloutPress={() => this.props.navigation.navigate("Community", { communityId: `${community._id}` })}>
<Callout>
<TouchableOpacity
style={styles.communityButton}>
<Text style={styles.communityButtonText}>{community.name}</Text>
<Text style={styles.descButtonText}>{community.description}</Text>
</TouchableOpacity>
</Callout>
</Marker>
I am now able to navigate to show screens from the map. Thanks to this post:
Marker click event on react native maps not working in react ios
Additional source:
onCalloutPress Callback that is called when a callout is tapped by the user.
https://github.com/react-native-community/react-native-maps/blob/master/docs/mapview.md

Rendering JSON data in react native

I'm currently using my api to render all posts in JSON to react native. But I keep getting this undefined error. And sometimes the data just wont render. Can anyone give me any help on rendering this data in react native? And explain to me what i'm doing wrong? I'm pretty new with JSON. Thanks :)
Here is my JSON:
{"data":[{"id":"1","type":"posts","links":{"self":"https://example.com/posts/1"},"attributes":{"title":"Laughter Post","context":{}},"relationships":{"user":{"links":{"self":"https://example.com/posts/1/relationships/user","related":"https://example.com/posts/1/user"}}}}]}
And here is my react native code:
import React, { Component } from "react";
import { FlatList, StyleSheet, Text, View } from "react-native";
export default class App extends Component {
state = {
data: []
};
componentWillMount() {
this.fetchData();
}
fetchData = async () => {
const response = await fetch("https://example.com/posts.json");
const json = await response.json();
this.setState({ data: json.data });
};
render() {
return (
<View style={styles.container}>
<FlatList
data={this.state.data}
keyExtractor={item => item.toString()}
renderItem={({ item }) =>
<Text>
{`${item.title}`}
</Text>}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
marginTop: 15,
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF"
}
});
It seems you are accessing title directly from the root, but it is inside key attributes
It should be
{`${item. attributes.title}`}
Or else if you can tell us the exact error, we can help you more regarding this issue.

navigator.geolocation.watchPosition not working correctly on ios device

I have a strange behavior and can not find a solution. In my React Native application I'm using the navigator.geolocation to determine the current position. My application is almost identical as the example in Facebook's Geolocation Code.
In the simulator my application works perfectly, but when I deploy it to my iphone the returning position (by getCurrentPosition and watchPosition) is not correctly. For example speed and heading is -1, accuracy is 65. Longitude and latitude seem to be valid, but not my real position (is in another country).
It does not matter whether I deploy the application via debug or release to the iphone, it always reacts same.
But if I start for example TomTom and put this application in the background, and then start my GeolocationExample application, everything works as it should.
My application I have created as follows:
react-native init GeolocationExample
And then I replaced the file index.ios.js with this code.
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
export default class GeolocationExample extends React.Component {
state = {
initialPosition: 'unknown',
lastPosition: 'unknown',
};
watchID: ?number = null;
componentDidMount() {
navigator.geolocation.getCurrentPosition(
(position) => {
var initialPosition = JSON.stringify(position);
this.setState({initialPosition});
},
(error) => alert(JSON.stringify(error)),
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
this.watchID = navigator.geolocation.watchPosition((position) => {
var lastPosition = JSON.stringify(position);
this.setState({lastPosition});
});
}
componentWillUnmount() {
navigator.geolocation.clearWatch(this.watchID);
}
render() {
return (
<View style={styles.main}>
<Text>
<Text style={styles.title}>Initial position: </Text>
{this.state.initialPosition}
</Text>
<Text>
<Text style={styles.title}>Current position: </Text>
{this.state.lastPosition}
</Text>
</View>
);
}
}
var styles = StyleSheet.create({
main: {
margin: 30
},
title: {
fontWeight: '500',
},
});
AppRegistry.registerComponent('GeolocationExample', () => GeolocationExample);
1st option : add parameter
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000, accuracy:10 //ten meters not in the document}
2nd option : set line 28
#define RCT_DEFAULT_LOCATION_ACCURACY kCLLocationAccuracyBest //default was kCLLocationAccuracyHundredMeters

Resources