Passing username and family name from google login - reactjs

I've managed to set up Google login using 'expo-google-app-auth'.
This is my Login.js, which handles the login page and the google login details and logic:
import React, { Component } from 'react'
import {Text,
View,
StyleSheet,
Image,
Alert} from 'react-native'
import { TouchableOpacity } from 'react-native-gesture-handler';
import { Provider as PaperProvider,
Button,
Caption} from 'react-native-paper'
import { createStackNavigator } from '#react-navigation/stack'
import { NavigationContainer } from '#react-navigation/native';
import MyDrawer from '../navigation/Drawer'
import QR from './QR'
const Stack = createStackNavigator();
import * as Google from 'expo-google-app-auth';
const IOS_CLIENT_ID =
"your-ios-client-id";
const ANDROID_CLIENT_ID =
"my-android-id";
class Login extends Component {
signInWithGoogle = async () => {
try {
const result = await Google.logInAsync({
iosClientId: IOS_CLIENT_ID,
androidClientId: ANDROID_CLIENT_ID,
scopes: ["profile", "email"]
});
if (result.type === "success") {
console.log("LoginScreen.js.js 21 | ", result.user.givenName, result.user.familyName, result.user.email, result.user.photoUrl);
this.props.navigation.navigate("MyDrawer", {
username: result.user.givenName,
lastname: result.user.familyName,
email: result.user.email,
photoUrl: result.user.photoUrl
}); //after Google login redirect to MyDrawer
return result.accessToken;
} else {
return { cancelled: true };
}
} catch (e) {
console.log('LoginScreen.js.js 30 | Error with login', e);
return { error: true };
}
};
render(){
return (
<PaperProvider>
<View style={styles.container}>
<View style={styles.imageCon}>
<Image
source={require('../img/logo-krug.png')}></Image>
</View>
<View style={styles.textCon}>
<Text style={styles.text}> Dobrodošli u eSTUDENT mobilnu aplikaciju!</Text>
</View>
<View style={styles.buttonCon}>
<Button
icon='camera'
mode='outlined'
onPress={this.signInWithGoogle}
>
google
</Button>
</View>
</View>
</PaperProvider>
)
}
}
export default function LoginStack() {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName='Login'
screenOptions={{
headerShown: false
}}>
<Stack.Screen name='MyDrawer' component={MyDrawer} />
<Stack.Screen name='Login' component={Login} />
</Stack.Navigator>
</NavigationContainer>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ecf0f1'
},
imageCon: {
height: '35%',
width: '100%',
justifyContent: "center",
alignItems: "center"
},
textCon:{
height:'20%',
alignItems: 'center',
justifyContent: 'center'
},
text: {
textAlign: "center",
fontSize: 20,
fontWeight: 'bold'
},
buttonCon:{
height: '30%',
justifyContent:'center',
alignItems: 'center'
},
});
And I want to pass the username, family name, email and profile picture to these 2 files.
Drawer.js, which handles the side Drawer and navigation:
import React from 'react'
import { createDrawerNavigator } from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
import { Ionicons, MaterialIcons, Feather } from '#expo/vector-icons';
import { ScrollView,
TouchableOpacity,
Text,
View,
Image,
StatusBar,
StyleSheet,
} from 'react-native'
import QR from '../screens/QR';
import Odabir from '../screens/Odabir'
import { SafeAreaView } from 'react-navigation';
import { Divider } from 'react-native-paper'
const Drawer = createDrawerNavigator();
function CustomDrawerContent(props) {
return(
<SafeAreaView style={{flex:1}}>
<View style={{height: 150, alignItems: 'center', justifyContent: 'center', marginTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight}}>
<Image source={require('../img/account.png')}
style={{height: 120, width: 120, borderRadius: 60}}
/>
</View>
<View style={{height: 50, alignItems:'center'}}>
<Text style={styles.naslov}> This is where I want to pass the username and last name </Text>
</View>
<Divider />
<ScrollView style={{marginLeft: 5,}}>
<TouchableOpacity
style={{marginTop: 20, marginLeft: 20}}
onPress={() => props.navigation.navigate('QR')}
>
<View style={{padding:10}}>
<Ionicons name='ios-qr-scanner' size={20} styles={{}}>
<Text style={styles.naslov}> QR</Text>
</Ionicons>
</View>
</TouchableOpacity>
<TouchableOpacity
style={{marginTop: 20, marginLeft: 20}}
onPress={() => props.navigation.navigate('Odabir')}
>
<View style={{padding:10}}>
<Ionicons name='ios-qr-scanner' size={20} styles={{}}>
<Text style={styles.naslov}> Odabir</Text>
</Ionicons>
</View>
</TouchableOpacity>
<TouchableOpacity
style={{marginTop: 20, marginLeft: 20}}
onPress={() => props.navigation.navigate('Odabir')}
>
<View style={{padding:10}}>
<Ionicons name='ios-qr-scanner' size={20} styles={{}}>
<Text style={styles.naslov}> Odabir</Text>
</Ionicons>
</View>
</TouchableOpacity>
</ScrollView>
</SafeAreaView>
)
}
export default function MyDrawer() {
return (
<NavigationContainer independent={true}>
<Drawer.Navigator initialRouteName='QR' drawerContent={props => CustomDrawerContent(props)}>
<Drawer.Screen
name="QR"
component={QR}
/>
<Drawer.Screen
name="Odabir"
component={Odabir}
/>
</Drawer.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
naslov: {
fontSize: 20,
},
})
and finally QR.js, which holds some basic information and I'd like to personalize it a bit since it's the 'Home' page users land on
import React, { Component } from 'react'
import {Text,
SafeAreaView,
View,
StyleSheet,
Image
} from 'react-native'
import Header from '../navigation/Header'
export default function QR({navigation}) {
return (
<SafeAreaView style={styles.container}>
<Header title='Moj QR' isHome={true} navigation={navigation}/>
<View style={styles.qrCon}>
<Image
style={styles.qr}
source={require('../img/QR_code_for_mobile_English_Wikipedia.svg.png')}
/>
</View>
<View style={styles.textCon}>
<Text style={styles.text}>This is where I want to pass the username and last name</Text>
<Text style={styles.text}>Ovo je tvoj QR kod</Text>
</View>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ecf0f1',
alignItems: 'center',
},
qrCon:{
width: '60%',
height: '60%',
alignItems: 'center',
justifyContent: 'center',
},
qr: {
width: '120%',
height: '120%',
resizeMode: 'contain'
},
textCon: {
height: '7%'
},
text:{
fontSize: 35,
fontWeight: '600'
},
buttonCon:{
height: '15%',
justifyContent:'center',
alignItems: 'center'
}
})
The example I'm following used {this.props.navigation.getParam("username")} but that isn't working for me. How would I exactly pass the data?

I had this issue recently. React navigation 5 doesn't support props.navigation.getParam instead you can use this.props.route.params to access the data you passed in your navigation prop. So to access the username you can use this.props.route.params.username;

The way to solve this, at least passing data to the Drawer.js component is to rewrite the code like this:
if (result.type === "success") {
console.log("LoginScreen.js.js 21 | ", result.user.givenName, result.user.familyName, result.user.email, result.user.photoUrl);
this.props.navigation.navigate("MyDrawer",
username = result.user.givenName,
lastname = result.user.familyName,
email = result.user.email,
photoUrl = result.user.photoUrl);
return result.accessToken;
;
Then just putting that as a variable in Drawer.js
<View style={{height: 30, alignItems:'center'}}>
<Text style={styles.naslov}>{username} {lastname}</Text>
</View>

Related

Expo app crashing on android on rendering components

When i render a screen in App.js the app crashes on android but works fine on android. If i render some function defined in App.js in renders on screen.
App.js
import React from 'react';
import {enableScreens} from 'react-native-screens';
enableScreens();
import { ActivityIndicator, View, Text, Button, TextInput, StyleSheet, TouchableOpacity } from "react-native";
import { NavigationContainer } from "#react-navigation/native";
import {createNativeStackNavigator} from "#react-navigation/native-stack";
import Main from "./screens/Main"
function HomeScreen({navigation}) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<TouchableOpacity onPress={() => {navigation.navigate("LoginPage")}}>
<Text>NEXT</Text>
</TouchableOpacity>
</View>
);
}
function S1({navigation}) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<TouchableOpacity onPress={() => {navigation.navigate("main")}}>
<Text>NEXT</Text>
</TouchableOpacity>
</View>
);
}
const Stack = createNativeStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" options={{headerShown : false}} component={HomeScreen} />
<Stack.Screen name="LoginPage" options={{headerShown : false}} component={S1} />
<Stack.Screen name="main" options={{headerShown : false}} component={Main} />
</Stack.Navigator>
</NavigationContainer>
);
}
Main.js
import react, {useState} from "react";
import { View, Text, Button, TextInput, StyleSheet, TouchableOpacity } from "react-native";
export default function Main({navigation}){
const options = [
{
name: "Games",
redirect: "Games"
},
{
name : "AR Tutorials",
redirect: "AR"
},
{
name : "Competition",
redirect : "Competition"
}
];
return(
<View style={styles.container}
>
{
options.map(op => (
<TouchableOpacity
style={styles.card}key={op.name} onPress={() => {navigation.navigate(op.redirect)}}>
<Text style={styles.cardText}>{op.name}</Text>
</TouchableOpacity>
))
}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center"
},
card: {
backgroundColor: "rgb(0, 100, 255)",
minHeight: "25%",
minWidth: "70%",
borderRadius: 1,
marginVertical: "1rem",
display: "flex",
justifyContent: "flex-end",
alignItems: "center"
},
cardText : {
marginBottom: "0.5rem"
}
});
Here functions HomeScreen and S1 renders but on navigating to Main the app crashes whiteout any logs.
I have tried building apk ind then running but it shows same behaviour.

I want to pass data to another screen by FlatList in react native

Hello guys am new on react native I want to build an app like news app with posts,I stack in how to pass the data in flatlist to another screen to open the screen with the post data i use V6 navigation Note I do the Navigation and the post touchable this is my code :
the import :
import { StyleSheet, Text, View ,Button ,FlatList,TouchableOpacity } from 'react-native';
import React,{useState} from 'react';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
Screen one :
function HomeScreen({navigation}) {
const [news,setnews]=useState([
{title:'React Native students can get the basic knowledge',by:'Chris brown',dateTime:'15 may',key:'1'},
{title:'whats happening here is that you are trying to',by:'charley',dateTime:'15 jan',key:'2'},
{title:'statuses. specifically, you have to look here:',by:'yami',dateTime:'15 jon',key:'3'},
{title:'screen you want to show, when the authentication status changes.',by:'maria',dateTime:'15 nov',key:'4'},
]);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<FlatList
data={news}
renderItem={({item})=>(
<TouchableOpacity onPress={()=>navigation.navigate('Detials' ,item)}>
<Text style={{fontSize:15,}}>{item.title}</Text>
</TouchableOpacity>
)}
/>
</View>
);
}
screen two:
function DetialsScreen({navigation}) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>{navigation.getParam('title')}</Text>
</View>
);
}
const Stack = createNativeStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Detials" component={DetialsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
screenone :
<FlatList
data={news}
renderItem={({item})=>(
<TouchableOpacity onPress={()=> this.props.navigation.navigate('ScreenTwo' , item)}>
<Text style={{fontSize:15,}}>{item.title}</Text>
</TouchableOpacity>
)}
/>
at screentwo you can get using this.props.route.params
export default class ScreenTwo extends Component {
constructor(props, ctx) {
super(props, ctx);
this.state = {
news: this.props.route.params
};
}
render() {
const news = this.state.news
return (
<View style={{flex: 1, margin: 30}}>
<Text>Title is : {news.title}{'\n'}{'\n'}by {news.by}</Text>
<Button
style={{marginTop: 20}}
onPress={() => this.props.navigation.goBack()}
title="Back"
color="#841584"
/>
</View>
);
}
}
for snack you can try here : https://snack.expo.dev/#edoofx/example1111
im using class anyway :D

CustomDrawerNavigator: Change Active and Inactive Background Colour

On react-navigation/drawer's DrawerItem, is there a way to add active and inactive background colour? I followed this document to implement this https://reactnavigation.org/docs/drawer-navigator/.
I have added theses code lines to the drawerItems. But it won't work for me.
drawerContentOptions={{
activeTintColor: '#fff', /* font color for active screen label */
activeBackgroundColor: '#68f', /* bg color for active screen */
inactiveTintColor: 'grey', /* Font color for inactive screens' labels */
}}
initialized by the following,
import * as React from 'react';
import {
Button,
View,
Text,
StyleSheet,
TouchableOpacity,
Image,
} from 'react-native';
import { useDispatch, useSelector } from 'react-redux';
import {
createDrawerNavigator,
DrawerContentScrollView,
DrawerItem,
} from '#react-navigation/drawer';
import Home from '../home/containers';
import NavigationService from '../../navigation/NavigationService';
import * as homeActions from '../../features/home/actions';
import * as loginActions from '../../features/login/actions';
import { Images } from '../../config';
import i18n from 'i18n-js';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
onPress={() => NavigationService.navigate('Notifications')}
title="Go to notifications"
/>
</View>
);
}
function NotificationsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button onPress={() => NavigationService.goBack()} title="Go back home" />
</View>
);
}
function CustomDrawerContent({ props, navigation }) {
const dispatch = useDispatch();
const outlets = useSelector((state) => state.homeReducer.outlets);
const defaultOutLet = useSelector((state) => state.homeReducer.defaultOutLet);
const drawerItems = outlets.map((outlet) => {
return (
console.log("############## nav drawr ################## " + outlet.name),
<DrawerItem
{...props}
key={outlet.userCompanyId}
label={outlet.name}
onPress={() => {
dispatch(homeActions.changeSelectedOutlet(outlet));
navigation.closeDrawer();
}}
/>
);
});
return (
<View style={styles.flexView}>
<View style={styles.container}>
<Image
style={styles.image}
source={Images.icons.logo}
resizeMode="contain"
/>
{defaultOutLet && <Text style={styles.text}>{defaultOutLet.name}</Text>}
</View>
<View style={styles.separator} />
<View style={styles.flexView}>{drawerItems}</View>
<View style={styles.separator} />
<View style={styles.bottomView}>
<TouchableOpacity
style={styles.logoutContainer}
onPress={() => {
dispatch(homeActions.clearUserCompany());
dispatch(loginActions.completeLogOutClearingUserData());
}}>
<Image
style={styles.logoutIcon}
source={Images.icons.power}
resizeMode="center"
/>
<Text style={styles.logoutText}>{i18n.t('common.logout')}</Text>
</TouchableOpacity>
</View>
</View>
);
}
const Drawer = createDrawerNavigator();
export default function DrawerNavigator() {
return (
<Drawer.Navigator
drawerContent={(props) => <CustomDrawerContent {...props} />}
initialRouteName="Home">
<Drawer.Screen name="Home" component={Home} />
</Drawer.Navigator>
);
}
const styles = StyleSheet.create({
container: {
flex: 0.3,
width: '100%',
backgroundColor: 'white',
},
flexView: {
flex: 1,
},
text: {
marginVertical: 12,
color: 'black',
textAlign: 'center',
},
logoutContainer: {
flexDirection: 'row',
alignItems: 'center',
width: '100%',
},
logoutText: {
color: 'gray',
},
logoutIcon: {
flex: 0.4,
},
image: {
flex: 1,
marginTop: 20,
alignSelf: 'center',
},
separator: {
width: '100%',
height: 1,
backgroundColor: 'gray',
},
bottomView: {
flex: 0.15,
width: '100%',
justifyContent: 'center',
},
});

Fetching data from URL works in ReactJS but does not work in Native

Fetching data from URL by search it, it works in React and not working in React Native how to solve the problem?
import React, { Component } from 'react'
import { SafeAreaView, StyleSheet, StatusBar, ScrollView, View, Text, TextInput, Button } from 'react-native';
import axios from 'axios';
export default class Main extends Component {
constructor(props){
super(props)
this.state={
ifscCode:"",
detail:{}
}
}
ifscSearch = () => {
const that = this;
axios.get('https://ifsc.razorpay.com/${this.state.ifscCode}')
.then(function (response) {
if (response.status == 200){
that.setState({detail:response.data})
console.log(data);
}
})
.catch(function (error) {
console.log(error);
})
}
ifscCodeChange = (Value) => {
this.setState({ifscCode:Value})
}
render() {
return (
<>
<StatusBar barStyle="light-content" />
<SafeAreaView>
<ScrollView>
<View style={styles.maincnt}>
<View style={styles.inpcnt}>
<NewIfsc ifscCodeChange={this.ifscCodeChange} />
</View>
<View style={styles.btncnt}>
<Button title='Search' style={styles.btn} onClick={this.ifscSearch} />
</View>
<View style={styles.listcnt}>
<Text>BANK: {this.state.detail.BANK}</Text>
<Text>{this.state.detail.BRANCH}</Text>
<Text>{this.state.detail.STATE}</Text>
<Text>{this.state.detail.CONTACT}</Text>
<Text>{this.state.detail.ADDRESS}</Text>
<Text>{this.state.detail.BANKCODE}</Text>
<Text>{this.state.detail.DISTRICT}</Text>
<Text>{this.state.detail.STATE}</Text>
<Text>{this.state.detail.IFSC}</Text>
</View>
</View>
</ScrollView>
</SafeAreaView>
</>
)
}
}
class NewIfsc extends Component {
render() {
return (
<View style={styles.inpcnt}>
<TextInput style={styles.txtinp} maxLength={11} placeholder='ifsc code search' onChange={(e)=>this.props.ifscCodeChange(e.target.Value)} />
</View>
)
}
}
const styles = StyleSheet.create({
maincnt:{
flex:1,
margin: 10,
backgroundColor: 'white'
},
inpcnt:{
marginTop: 20,
},
btncnt:{
marginTop: 20,
},
listcnt:{
marginTop: 20
},
txtinp:{
width: 350,
height: 50,
borderRadius: 25,
borderWidth: 2,
borderColor: 'indigo',
alignSelf: 'center',
padding: 10
},
btn:{
width: 100,
height: 70,
alignSelf: 'center'
},
listcnt:{
marginTop: 50,
alignContent: 'center',
justifyContent: 'center'
}
});

how to make initialParams updated

I want to update initialParams of react native navigation on clicking of the menu item
import React, { useState } from 'react';
import {createStackNavigator} from '#react-navigation/stack'
import { NavigationContainer } from '#react-navigation/native';
import userMain from './../../components/users/userMain';
import { View, Icon } from 'native-base';
export const UserStack = () => {
const Stack = new createStackNavigator()
const [toggleSearch, setToggleSearch] = useState(true)
const changeStyleToggle = () => {
setToggleSearch( !toggleSearch )
// console.log('toggle search here ==== ', toggleSearch)
}
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="User Homepage"
component={userMain}
initialParams={{ toggleSearch: toggleSearch}}
options = {{
title: 'My home',
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
headerRight: () => (
<View style={{flexDirection:'row', justifyContent:'space-evenly', width:120}}>
<Icon name='home' onPress={() => changeStyleToggle()} />
<Icon name='home' />
<Icon name='home' />
</View>
),
}}
/>
</Stack.Navigator>
</NavigationContainer>
)
}
the component i am calling is userMain where i am calling initialParams value and on behalf of that i want to change style
import React from 'react'
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native'
import { Input } from 'native-base';
const userMain = (props) => {
const {toggleSearch} = props.route.params;
console.log(toggleSearch)
const check = toggleSearch == true ? 'true!!' : 'false!!'
return (
<View style={styles.container}>
<Input
placeholder="search"
style={styles.searchInput}
/>
<Text>user homepage here</Text>
<Text>{check}</Text>
<TouchableOpacity style={styles.btn}>
<Text style={styles.btnText}> + </Text>
</TouchableOpacity>
</View>
)
}
const styles = StyleSheet.create({
container: {
alignItems: 'center', flex: 1, justifyContent: 'center',
},
btn: {
position: 'absolute', justifyContent: 'center', alignItems: 'center',
bottom:10, right:10, width:60, height: 60,
backgroundColor: '#fff', borderRadius: 50, borderColor: '#000',borderWidth:1,
},
btnText: {
fontSize: 50, color: 'black',
},
searchInput: {
position:'absolute', top: 0, borderWidth: 1, width: 300, opacity:0
}
})
export default userMain
i have checked on clicking the icon state which is toggleSearch is updating but it is not updating the initialParams hence it is not working on userMain component as well .

Resources