Get user city from location coords data, in react native? - reactjs

I got the coords but cannot get it to show the city. I almost got it. I even got the API key it requires but cannot do anything more. Please help me, I am going nuts. If you have any other way that I could do it, you can show it aswell it would be appreciated. Thank you. Here's what I could do so far:
import React from "react";
import { Button, PermissionsAndroid, SafeAreaView, StatusBar, StyleSheet, Text, View, Platform } from "react-native";
import GetLocation from 'react-native-get-location'
const locationToAdress = async(location) =>
{
const locationPublish = `${location.latitude},${location.longitude}`; //PUBLISH
const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${locationPublish}&sensor=true&key=${config.myGoogleAPIisaSecretnumber}`;
fetch(url)
.then((result) => {
const { results } = result;
console.log(results);
})
.catch((e) => {
console.log(e);
});
}
const requestLokasyonPermission = async () => {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
GetLocation.getCurrentPosition({
enableHighAccuracy: true,
timeout: 15000,
})
.then(location => {
console.log(location);
console.log(location.latitude);
console.log("lokasyon seysi bu" + location.longitude);
locationToAdress(location);
})
.catch(error => {
const { code, message } = error;
console.warn(code, message);
})
);
};
const requestCameraPermission = async () => {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: "Cool Photo App Camera Permission",
message:
"Cool Photo App needs access to your camera " +
"so you can take awesome pictures.",
buttonNeutral: "Ask Me Later",
buttonNegative: "Cancel",
buttonPositive: "OK"
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You can use the camera");
} else {
console.log("Camera permission denied");
}
} catch (err) {
console.warn(err);
}
};
const App = () => (
<View style={styles.container}>
<Text style={styles.item}>Try permissions</Text>
<Button title="request permissions" onPress={
() => { requestCameraPermission();}
}/>
<Text style={styles.item}>Try permissions</Text>
<Button title="request permissions" onPress={
() => { requestLokasyonPermission();}
}/>
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
paddingTop: StatusBar.currentHeight,
backgroundColor: "#ecf0f1",
padding: 8
},
item: {
margin: 24,
fontSize: 18,
fontWeight: "bold",
textAlign: "center"
}
});
export default App;

In locationToAdress you have used geocode service which converts address to latitude and longitude. In your case, you want the opposide - i.e. from latitude and longitude coordinates to address for which one should use reverse geocoding service as given here

I haven't worked on react-native-get-location, but you can refer below example for your code.
I am using react-native-geolocation-service.
Remove ${config.} before API Key
P.S. : Never Post Your Google Map API Key directly on any site.
import React from "react";
import { Button, PermissionsAndroid, SafeAreaView, StatusBar, StyleSheet, Text, View, Platform } from "react-native";
import Geolocation from 'react-native-geolocation-service'
const locationToAdress = async (location) => {
const locationPublish = `${location.latitude},${location.longitude}`; //PUBLISH
const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${locationPublish}&sensor=true&key=YOURGOOGLEMAPAPIKEY`;
fetch(url)
.then((result) => {
console.log(result);
})
.catch((e) => {
console.log(e);
});
}
const requestLokasyonPermission = async () => {
if (Platform.OS === "android") {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: "Location Permission",
message:
"This App needs access to your location " +
"so we can know where you are.",
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You can use locations ");
} else {
console.log("Location permission denied");
}
} catch (err) {
console.warn(err);
}
}
Geolocation.getCurrentPosition(
(location) => {
console.log(location);
locationToAdress(location.coords)
},
(error) => {
console.log(error);
},
{ enableHighAccuracy: false, timeout: 200000, maximumAge: 1000 }
);
};
const requestCameraPermission = async () => {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: "Cool Photo App Camera Permission",
message:
"Cool Photo App needs access to your camera " +
"so you can take awesome pictures.",
buttonNeutral: "Ask Me Later",
buttonNegative: "Cancel",
buttonPositive: "OK"
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You can use the camera");
} else {
console.log("Camera permission denied");
}
} catch (err) {
console.warn(err);
}
};
const App = () => (
<View style={styles.container}>
<Text style={styles.item}>Try permissions</Text>
<Button title="request permissions" onPress={
() => { requestCameraPermission(); }
} />
<Text style={styles.item}>Try permissions</Text>
<Button title="request permissions" onPress={
() => { requestLokasyonPermission(); }
} />
</View>
);
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
paddingTop: StatusBar.currentHeight,
backgroundColor: "#ecf0f1",
padding: 8
},
item: {
margin: 24,
fontSize: 18,
fontWeight: "bold",
textAlign: "center"
}
});
export default App;

Related

Expo app keeps returning TypeError: undefined is not an object (evaluating 'function')

I am creating a mobile app that takes a picture and then returns the objects it detected. the way it works is that i have heroku running the ml model api. the weird thing about this error is that it happened after my code worked and sent an api request which then returned a json of what it detected. and when i ran it again it gave me [TypeError: undefined is not an object (evaluating '_expo.ImageManipulator.manipulateAsync')]. i looked at the value of image and asset to see if they are undefined and the console printed false. i even tried
console.log(typeof image==='undefined')
console.log(typeof asset==='undefined')
console.log(typeof image=='undefined')
console.log(typeof asset=='undefined')
just to make sure that the value of the variables aren't undefined. i then commented out the function to see what would happen and i got [TypeError: undefined is not an object (evaluating '_this.toServer')]. i then restarted the expo server and did everything i did above again but it keeps giving me [TypeError: undefined is not an object (evaluating '_expo.ImageManipulator.manipulateAsync')]. the code below is the code for the function that saves the image and makes a post request.
const takePicture = async () => {
if (cameraRef) {
try {
const data = await cameraRef.current.takePictureAsync();
console.log(data);
setImage(data.uri);
} catch (error) {
console.log(error);
}
}
};
uriToBase64 = async (uri) => {
let base64 = await FS.readAsStringAsync(uri, {
encoding: FS.EncodingType.Base64,
});
return base64;
};
const savePicture = async () => {
if (image) {
try {
const asset = await MediaLibrary.createAssetAsync(image);
console.log(image===undefined)
console.log(asset===undefined)
console.log(image==undefined)
console.log(asset===undefined)
let manipResult = await ImageManipulator.manipulateAsync(
asset,[{ resize: { width: 800, height: 800 } }],{ format: 'jpg' });
let assetResized = await MediaLibrary.createAssetAsync(manipResult);
await this.toServer({
type:"image",
base64: uriToBase64(assetResized),
uri: assetResized,
});
setImage(null);
console.log('saved successfully');
} catch (error) {
console.log(error);
}
}
};
also if i do:
if(!(image==undefined))
to make it so that if the image is undefined it won't do anything i get
LOG [Error: Argument of an incompatible class: class java.util.HashMap cannot be passed as an argument to parameter expecting class java.lang.String.]
WARN Possible Unhandled Promise Rejection (id: 0):
Error: Argument of an incompatible class: class java.util.HashMap cannot be passed as an argument to parameter expecting class java.lang.String.
promiseMethodWrapper#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:22934:45
http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:114097:40
readAsStringAsync$#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:118249:92
tryCatch#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24610:23
http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24590:34
tryCatch#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24610:23
invoke#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24648:30
http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24672:19
tryCallTwo#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:30323:9
doResolve#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:30487:25
Promise#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:30346:14
callInvokeWithMethodAndArg#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24671:33
_invoke#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24676:157
async#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24762:69
readAsStringAsync#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:118236:38
_callee3$#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:120465:69
tryCatch#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24610:23
http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24590:34
tryCatch#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24610:23
invoke#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24648:30
http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24672:19
tryCallTwo#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:30323:9
doResolve#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:30487:25
Promise#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:30346:14
callInvokeWithMethodAndArg#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24671:33
_invoke#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24676:157
async#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24762:69
_callee3#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:120460:40
_callee5$#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:120529:36
tryCatch#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24610:23
http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24590:34
tryCatch#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24610:23
invoke#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24648:30
http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:24654:19
tryCallOne#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:30314:16
http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:30415:27
http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:31506:26
_callTimer#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:31406:17
_callReactNativeMicrotasksPass#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:31441:17
callReactNativeMicrotasks#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:31648:44
__callReactNativeMicrotasks#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:23414:46
http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:23193:45
__guard#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:23397:15
flushedQueue#http://192.168.1.4:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false:23192:21
flushedQueue#[native code]
invokeCallbackAndReturnFlushedQueue#[native code]
here is the entire code:
import React, { useState, useEffect, useRef } from 'react';
import { Text, View, StyleSheet, TouchableOpacity, Image } from 'react-native';
import Constants from 'expo-constants';
import { Camera, CameraType } from 'expo-camera';
import * as MediaLibrary from 'expo-media-library';
import { MaterialIcons } from '#expo/vector-icons';
import Button from './src/components/Button';
import axios from 'axios'
import { Buffer } from "buffer";
import * as FS from "expo-file-system";
import { ImageManipulator } from 'expo';
export default function App() {
const [hasCameraPermission, setHasCameraPermission] = useState(null);
const [image, setImage] = useState(null);
const [type, setType] = useState(Camera.Constants.Type.back);
const [flash, setFlash] = useState(Camera.Constants.FlashMode.off);
const cameraRef = useRef(null);
useEffect(() => {
(async () => {
MediaLibrary.requestPermissionsAsync();
const cameraStatus = await Camera.requestCameraPermissionsAsync();
setHasCameraPermission(cameraStatus.status === 'granted');
})();
}, []);
const takePicture = async () => {
if (cameraRef) {
try {
const data = await cameraRef.current.takePictureAsync();
console.log(data);
setImage(data.uri);
} catch (error) {
console.log(error);
}
}
};
uriToBase64 = async (uri) => {
let base64 = await FS.readAsStringAsync(uri, {
encoding: FS.EncodingType.Base64,
});
return base64;
};
toServer = async (mediaFile) => {
url = "censored url so that trolls wont use it ";
let response = await FS.uploadAsync(url, mediaFile.uri, {
headers: {
"content-type": "image/jpeg",
},
httpMethod: "POST",
uploadType: FS.FileSystemUploadType.BINARY_CONTENT,
});
console.log(response);
};
const savePicture = async () => {
if (image) {
try {
const asset = await MediaLibrary.createAssetAsync(image);
console.log(typeof image==='undefined')
console.log(typeof asset==='undefined')
console.log(typeof image=='undefined')
console.log(typeof asset=='undefined')
await this.toServer({
type:"image",
base64: uriToBase64(asset),
uri: asset,
});
setImage(null);
console.log('saved successfully');
} catch (error) {
console.log(error);
}
}
};
if (hasCameraPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View style={styles.container}>
{!image ? (
<Camera
style={styles.camera}
type={type}
ref={cameraRef}
flashMode={flash}
>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
paddingHorizontal: 30,
}}
>
<Button
title=""
icon="retweet"
onPress={() => {
setType(
type === CameraType.back ? CameraType.front : CameraType.back
);
}}
/>
<Button
onPress={() =>
setFlash(
flash === Camera.Constants.FlashMode.off
? Camera.Constants.FlashMode.on
: Camera.Constants.FlashMode.off
)
}
icon="flash"
color={flash === Camera.Constants.FlashMode.off ? 'gray' : '#fff'}
/>
</View>
</Camera>
) : (
<Image source={{ uri: image }} style={styles.camera} />
)}
<View style={styles.controls}>
{image ? (
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
paddingHorizontal: 50,
}}
>
<Button
title="Re-take"
onPress={() => setImage(null)}
icon="retweet"
/>
<Button title="Save" onPress={savePicture} icon="check" />
</View>
) : (
<Button title="Take a picture" onPress={takePicture} icon="camera" />
)}
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#000',
padding: 8,
},
controls: {
flex: 0.5,
},
button: {
height: 40,
borderRadius: 6,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
text: {
fontWeight: 'bold',
fontSize: 16,
color: '#E9730F',
marginLeft: 10,
},
camera: {
flex: 5,
borderRadius: 20,
},
topControls: {
flex: 1,
},
});

REACT NATIVE: fetching array of image from firestore database collection to carousel

Good day.
I have managed to fetch an array of images from firestore database collection, the only problem is that it seems that I cannot loop over the array that I am retrieving from the database.
I need to dynamically display my images on the carousel.
import React, { useState, useEffect, useCallback } from 'react';
import { Text, Dimensions, StyleSheet, View, Image } from 'react-native';
import { SwiperFlatList } from 'react-native-swiper-flatlist';
import firestore from '#react-native-firebase/firestore';
import { white } from 'react-native-paper/lib/typescript/styles/colors';
import { color } from 'react-native-reanimated';
import Carousel from 'react-native-reanimated-carousel';
//const colors = ["tomato", "thistle", "skyblue", "teal"];
const names = [{"AdImage": "https://firebasestorage.googleapis.com/v0/b/pindot-65e7c.appspot.com/o/Ads%2FJB.png?alt=media&token=377f1629-6807-4343-b826-93d1c2bc5de6"}, {"AdImage": "https://firebasestorage.googleapis.com/v0/b/pindot-65e7c.appspot.com/o/Ads%2Fgymtarp.png?alt=media&token=b2d1c923-2b5c-4066-bf8f-dc12de399059"}, {"AdImage": "https://firebasestorage.googleapis.com/v0/b/pindot-65e7c.appspot.com/o/photos%2Fb75d0848-b37f-4584-ab46-f355ca838e83.jpg?alt=media&token=adaa8559-de91-4ced-b056-84300123102e"}, {"AdImage": "https://firebasestorage.googleapis.com/v0/b/pindot-65e7c.appspot.com/o/Ads%2FSANDO.png?alt=media&token=274c946b-7f20-4c07-8545-431a0558257c"}];
const App = () => {
const [ads, setAds] = useState([]); // Initial empty array of ads
useEffect(() => {
const subscriber = firestore()
.collection('AdsDB')
//.orderBy('Menu', 'asc')
.onSnapshot(querySnapshot => {
//const ads = [];
/*
querySnapshot.forEach(documentSnapshot => {
ads.push({
...documentSnapshot.data(),
key: documentSnapshot.id,
});
});
*/
querySnapshot.forEach(doc => {
const { AdImage } = doc.data();
ads.push({
//id: doc.id,
AdImage,
//Price,
});
});
setAds(ads);
console.log(ads);
//console.log(Object.entries(ads));
});
// Unsubscribe from events when no longer in use
return () => subscriber();
}, []);
return (
<View style={styles.container}>
<SwiperFlatList
autoplay
autoplayDelay={2}
autoplayLoop
index={2}
showPagination
data={ads}
renderItem={({ item }) => (
<View style={[styles.child, { backgroundColor: item }]}>
<Text style={styles.text}>{item.AdImage}</Text>
<Image
style={{
width: "100%",
height: "30%",
position: 'absolute',
top:0,
alignItems: 'center',
justifyContent: 'center'}}
source={{uri : item.AdImage}}
resizeMode={'stretch'} // cover or contain its upto you view look
/>
</View>
)}
/>
</View>
)
};
const { width } = Dimensions.get('window');
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: 'white', },
child: { width, justifyContent: 'center', height: '100%' },
text: { fontSize: width * 0.1, textAlign: 'center' },
});
export default App;
Thank you for answering my question. Mabuhay! I'm from the Philippines.
The problem I am seeing is that probably meanwhile you are receiving asynchronously the snapshots, the setState did not ended running (a race condition between the velocity receiving snapshots and the exact time needed to persist the state)
I would try to delay the state change and use the previous state value in the setter, like this:
useEffect(() => {.
const subscriber = firestore()
.collection('AdsDB')
.onSnapshot(querySnapshot => {
querySnapshot.forEach(doc => {
const { AdImage } = doc.data();
setTimeout(() => {
setAds((prevAds) => [...prevAds, AdImage]);
}, 500);
});
console.log(ads);
//console.log(Object.entries(adsFromFirebase));
});
These are my code, Sir. It gives an empty array.
import React, { useState, useEffect, useCallback } from 'react';
import { Text, Dimensions, StyleSheet, View, Image } from 'react-native';
import { SwiperFlatList } from 'react-native-swiper-flatlist';
import firestore from '#react-native-firebase/firestore';
import { white } from 'react-native-paper/lib/typescript/styles/colors';
import { color } from 'react-native-reanimated';
const colors = ["tomato", "thistle", "skyblue", "teal"];
const names = [{"AdImage": "https://firebasestorage.googleapis.com/v0/b/pindot-65e7c.appspot.com/o/Ads%2FJB.png?alt=media&token=377f1629-6807-4343-b826-93d1c2bc5de6"}, {"AdImage": "https://firebasestorage.googleapis.com/v0/b/pindot-65e7c.appspot.com/o/Ads%2Fgymtarp.png?alt=media&token=b2d1c923-2b5c-4066-bf8f-dc12de399059"}, {"AdImage": "https://firebasestorage.googleapis.com/v0/b/pindot-65e7c.appspot.com/o/photos%2Fb75d0848-b37f-4584-ab46-f355ca838e83.jpg?alt=media&token=adaa8559-de91-4ced-b056-84300123102e"}, {"AdImage": "https://firebasestorage.googleapis.com/v0/b/pindot-65e7c.appspot.com/o/Ads%2FSANDO.png?alt=media&token=274c946b-7f20-4c07-8545-431a0558257c"}];
const App = () => {
const [ads, setAds] = useState([]); // Initial empty array of ads
useEffect(() => {
const subscriber = firestore()
.collection('AdsDB')
.onSnapshot(querySnapshot => {
querySnapshot.forEach(doc => {
const { AdImage } = doc.data();
setTimeout(() => {
setAds((prevAds) => [...prevAds, AdImage]);
}, 500);
});
console.log(ads);
//console.log(Object.entries(adsFromFirebase));
});
// Unsubscribe from events when no longer in use
return () => subscriber();
}, []);
/*
useEffect(() => {
const subscriber = firestore()
.collection('AdsDB')
//.orderBy('Menu', 'asc')
.onSnapshot(querySnapshot => {
//const ads = [];
/*
querySnapshot.forEach(documentSnapshot => {
ads.push({
...documentSnapshot.data(),
key: documentSnapshot.id,
});
});
querySnapshot.forEach(doc => {
const { AdImage } = doc.data();
ads.push({
//id: doc.id,
AdImage,
//Price,
});
});
setAds(ads);
//console.log(ads);
//console.log(Object.entries(ads));
});
// Unsubscribe from events when no longer in use
return () => subscriber();
}, []);
*/
return (
<View style={styles.container}>
<SwiperFlatList
autoplay
autoplayDelay={2}
autoplayLoop
index={2}
data={ads}
renderItem={({ item }) => (
<View style={[styles.child, { backgroundColor: item.colors }]}>
<Text style={styles.text}>{item.AdImage}</Text>
<Image
style={{
width: "100%",
height: "30%",
position: 'absolute',
top:0,
alignItems: 'center',
justifyContent: 'center'}}
source={{uri : item.AdImage}}
resizeMode={'stretch'} // cover or contain its upto you view look
/>
{/*}*/}
</View>
)}
/>
</View>
)
};
const { width } = Dimensions.get('window');
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: 'white', },
child: { width, justifyContent: 'center', height: '100%' },
text: { fontSize: width * 0.1, textAlign: 'center' },
});
export default App;
This is the output.
LOG Running "myApp" with {"rootTag":21}
LOG []

undefined is not an object (evaluating 'this.state.user.avatar')

Image of Error
I am using ios emulator and keep on receiving this error when i go to run the profile page. It first loads for a little bit then stops and the error pops up it says it's on the 'this.state.user.avatar' but i can't seem to see what i wrong with it? what am i doing wrong? if someone can help me that would be great!
This is my ProfileScreen.js file
import React from "react";
import {View, Text, StyleSheet, TouchableOpacity, Button, Image } from "react-native";
import Fire from '../utilities/Fire';
export default class ProfileScreen extends React.Component {
state = {
user: {}
};
unsubscribe = null;
componentDidMount() {
const user = this.props.uid || Fire.shared.uid
this.unsubscribe = Fire.shared.firestore
.collection("users")
.doc(user)
.onSnapshot(doc => {
this.setState({ user: doc.data() });
});
}
componentWillUnmount() {
this.unsubscribe();
};
render() {
return(
<View style={styles.container}>
<View style = {{ MarginTop: 64, alignItems: "Center" }}>
<View style={styles.avatarContainer}>
<Image style={styles.avatar} source={this.state.user.avatar ? { uri: this.state.user.avatar } : require("../assets/avatar.png")}
/>
</View>
<Text style={styles.name}>{this.state.user.name}</Text>
</View>
<View style={styles.subContainer}>
<View style={styles.stat}>
<Text style={styles.info}>8/10</Text>
<Text style={styles.Title}>Rewards</Text>
</View>
<View style={styles.stat}>
<Text style={styles.info}>80/100</Text>
<Text style={styles.Title}>Badges</Text>
</View>
</View>
<Button onPress={() => {Fire.shared.signOUt()}} title="Log Out" />
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flex: 1,
},
avatarContainer:{
shadowColor: "#151734",
shadowRadius: 15,
shadowOpacity: 0.4
},
avatar: {
width: 136,
height: 136,
borderRadius: 68
},
name: {
marginTop: 24,
fontSize: 16,
fontWeight: "600"
},
subContainer: {
flexDirection: "row",
justifyContent: "space-between",
margin: 32,
},
stat: {
alignItems:"center",
},
info: {
color: "#4F566D",
fontSize: 18,
fontWeight: "300"
},
Title: {
color: "#C3C5CD",
fontSize: 12,
fontWeight: "500",
marginTop: 4
}
});
This is my Fire.js file
import FirebaseKeys from '../config';
import firebase from 'firebase';
require("firebase/firestore");
class Fire{
constructor() {
firebase.initializeApp(FirebaseKeys);
}
addPost = async({ text, localUri }) => {
const remoteUri = await this.uploadPhotoAsync(localUri, 'photos/${this.uid}/${Date.now()}');
return new Promise ((res, rej) => {
this.firestore
.collection("posts")
.add ({
text,
uid: this.uid,
timestamp: this.timestamp,
image: remoteUri
})
.then(ref => {
res(ref);
})
.catch(error => {
rej(error);
});
});
};
uploadPhotoAsync = async (uri, filename) => {
return new Promise(async (res, rej) => {
const response = await fetch(uri);
const file = await response.blob();
let upload = firebase
.storage()
.ref(filename)
.put(file);
upload.on(
"state_changed",
snapshot => {},
err => {
rej(err);
},
async () => {
const url = await upload.snapshot.ref.getDownloadURL();
res(url);
}
);
});
};
createUser = async user => {
let remoteUri = null
try {
await firebase.auth().createUserWithEmailAndPassword(user.email, user.password)
let db = this.firestore.collection("users").doc(this.uid)
db.set({
name: user.name,
email: user.email,
avatar: null
})
if (user.avatar) {
remoteUri = await this.uploadPhotoAsync(user.avatar, 'avatars/${this.uid}')
db.set({avatar: remoteUri }, { merge: true})
}
} catch (error) {
alert("Error: ", error);
}
};
signOut = () => {
firebase.auth().signOut();
};
get firestore(){
return firebase.firestore();
}
get uid() {
return (firebase.auth().currentUser || {}).uid;
}
get timestamp() {
return Date.now();
}
}
Fire.shared = new Fire();
export default Fire;
If you want to set the state like that you need to do it in the constructor like this:
constructor(props) {
super(props);
this.state = {
user: {}
}
}
So add that code to the top of the class and it should actually set the user to an empty object..
Everywhere else in the app you use setState....
Try to change user{} by user[]

Google.logInAsync function for OAuth not doing anything in React Native

Google.logInAsync function which is supposed to used for OAuth in React Native, is not giving any response, or is stuck. Take a look at my code, from line 14 to 36. This signIn function is calling Google.logInAsync and is stuck there. No error, nothing. How ever when I press the button again, and the signIn function gets called again, an error is passed: Error: Cannot start a new task while another task is currently in progress: Get Auth
This is my code currently. It shows a label " Sign In With Google" and a Button on the screen. Tapping on the button starts this.signIn funtion, prints "Started logInAsync" on the debugger screen, but theGoogle.logInAsync never completes, no errors are thrown anywhere. console.log('Completed logInAsync') never gets executed!
import {Google} from "expo"
...
console.log('Starting logInAsync')
const result = await Google.logInAsync({
androidClientId:
"<CLIENT_ID>",
scopes: ["profile", "email"]
})
console.log('Completed logInAsync')
that gave an error saying install "expo-google-app-auth"
I installed that module and then changed the import and the function
import * as Google from "expo-google-app-auth"
...
console.log('Starting logInAsync')
const result = await Google.logInAsync({
...
})
console.log('Completed logInAsync')
And after there,
import { StyleSheet, Text, View, Image, Button } from "react-native"
import * as Google from "expo-google-app-auth"
export default class App extends React.Component {
constructor(props) {
super(props)
this.state = {
signedIn: false,
name: "",
photoUrl: ""
}
}
signIn = async () => {
try {
console.log('Starting logInAsync')
const result = await Google.logInAsync({
androidClientId:
"860657237026-jfosg5hu52u1vedclccs1vgihghva534.apps.googleusercontent.com",
scopes: ["profile", "email"]
})
console.log('Completed logInAsync')
if (result.type === "success") {
this.setState({
signedIn: true,
name: result.user.name,
photoUrl: result.user.photoUrl
})
} else {
console.log("Cancelled!")
}
} catch (e) {
console.log("Error: ", e)
}
}
render() {
return (
<View style={styles.container}>
{this.state.signedIn ? (
<LoggedInPage name={this.state.name} photoUrl={this.state.photoUrl} />
) : (
<LoginPage signIn={this.signIn} />
)}
</View>
)
}
}
const LoginPage = props => {
return (
<View>
<Text style={styles.header}>Sign In With Google</Text>
<Button title="Sign in with Google" onPress={() => props.signIn()} />
</View>
)
}
const LoggedInPage = props => {
return (
<View style={styles.container}>
<Text style={styles.header}>Welcome:{props.name}</Text>
<Image style={styles.image} source={{ uri: props.photoUrl }} />
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center"
},
header: {
fontSize: 25
},
image: {
marginTop: 15,
width: 150,
height: 150,
borderColor: "rgba(0,0,0,0.2)",
borderWidth: 3,
borderRadius: 150
}
})
No error occur in this code, except if you press the SignIn button twice. I am on the latest version of Node, React-Native and Expo as of now.

Loading Component in React native with Firebase and redux

Click here to View Page
I need your help here. I want to add Activity indicator with timeout after Login button is pressed but login button is already configured to loginUser() function! I just need to show activity indicator for some secs and login the user when button is pressed! Thankyou I been trying for week. I'm helpless. So please help me!
import React, { Component } from 'react';
import { StyleSheet, View, Text, Alert, TouchableOpacity, ActivityIndicator } from 'react-native';
import { Form, Input, Item, Button, Label, Body, } from 'native-base';
import { login } from "../actions";
import { Actions } from "react-native-router-flux";
import { connect } from "react-redux";
import { colors } from "../../../colors";
class UserLoginForm extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
};
this.loginUser = this.loginUser.bind(this);
this.loginSuccessCallback = this.loginSuccessCallback.bind(this);
this.loginErrorCallback = this.loginErrorCallback.bind(this);
}
forgotPassword() {
Actions.ForgotPassword();
};
loginSuccessCallback(user) {
};
loginErrorCallback(error) {
switch (error.code) {
case 'auth/user-not-found':
Alert.alert('Error', 'User not found. New user? SignUp');
break;
case 'auth/wrong-password':
Alert.alert('Error', 'Wrong Password');
break;
}
};
loginUser() {
const { email, password } = this.state;
const data = { email, password };
this.props.dispatch(login(data, this.loginSuccessCallback, this.loginErrorCallback));
};
render() {
return (
<View style={styles.container}>
<Form>
<Item floatingLabel>
<Label>Email</Label>
<Input
autoCorrect={false}
autoCapitalize="none"
returnKeyType="done"
onChangeText={(email) => this.setState({ email })} />
</Item>
<Item floatingLabel>
<Label>Password</Label>
<Input
secureTextEntry={true}
autoCorrect={false}
autoCapitalize="none"
returnKeyType="go"
onSubmitEditing={this.loginUser}
onChangeText={(password) => this.setState({ password })} />
</Item>
<Button style={styles.loginButton}
full
rounded
onPress={this.loginUser}>
<Text style={{ fontWeight: 'bold', color: 'white', fontSize: 20 }}>Login</Text>
</Button>
<TouchableOpacity onPress={this.forgotPassword}>
<Text style={styles.forgotButton}>Forgot Password?</Text>
</TouchableOpacity>
<--------------Loading Component ------------------>
<View style={styles.loading}>
<ActivityIndicator
animating={this.state.animating}
style={[{ height: 80 }]}
color="#C00"
size="large"
hidesWhenStopped={true} />
<Text style={{ color: 'red' }}>loading..</Text>
</View>
<------------------------------------------------------------------->
</Form>
</View>
);
}
}
function mapStateToProps(state, props) {
return {
user: state.authReducer.user,
};
}
export default connect(
mapStateToProps,
null
)(UserLoginForm);
const styles = StyleSheet.create({
container: {
marginTop: 10
},
loginButton: {
alignSelf: 'center',
marginTop: 10,
width: 250
},
forgotButton: {
alignSelf: 'center',
marginTop: 15,
color: colors.white
},
loading: {
position: 'absolute',
opacity: 0.5,
height: '50%',
width: '35%',
backgroundColor: 'black',
alignSelf: 'center',
alignItems: 'center',
borderBottomLeftRadius: 20,
borderBottomRightRadius: 20,
borderTopRightRadius: 20,
borderTopLeftRadius: 20,
}
})
Login function goes here..
<--------------------------------------------------------------------------------------------------->
import * as t from "./actionTypes";
import {auth} from "../../config/firebase";
import * as api from "./api";
export function register(data, successCB, errorCB) {
return dispatch => {
api.register(data, function (success, data, error) {
if (success) {
successCB(data);
} else if (error) errorCB(error);
});
};
}
export function checkLoginStatus(callback) {
return dispatch => {
auth.onAuthStateChanged(authUser => {
let isLoggedIn = authUser !== null;
if (isLoggedIn) {
api.getUser(authUser, function (success, {exists, user}, error) {
if (success) {
if (exists) {
dispatch({type: t.USER_LOGGED_IN, data: user});
callback(true, 'user');
}
else {
api.getEmployee(authUser, function (success, {exists, user}, error) {
if (success && exists) {
dispatch({type: t.EMPLOYEE_LOGGED_IN, data: user});
callback(true, 'employee');
} else {
dispatch({type: t.LOGGED_OUT});
callback(false);
}
})
}
} else if (error) {
//unable to get user
dispatch({type: t.LOGGED_OUT});
callback(false);
}
});
} else {
dispatch({type: t.LOGGED_OUT});
callback(false);
}
});
};
}
export function login(data, successCB, errorCB) {
return dispatch => {
api.login(data, function (success, data, error) {
if (success) {
if (data.exists) dispatch({type: t.USER_LOGGED_IN, data: data.user});
successCB(data);
} else if (error) errorCB(error);
});
};
}
export function logout(errorCB) {
return dispatch => {
api.logout(function (success, data, error) {
if (success) {
dispatch({type: t.LOGGED_OUT});
} else if (error) errorCB(error);
});
};
}
export function loginEmployee(data, successCB, errorCB) {
return dispatch => {
api.loginEmployee(data, function (success, data, error) {
if (success) {
if (data.exists) dispatch({type: t.EMPLOYEE_LOGGED_IN, data: data.user});
successCB(data);
} else if (error) errorCB(error);
});
};
}

Resources