I'm building a react native app for sign up and login. The backend works well. I checked with Postman. But the frontend doesn't call the server for the post request.
This is the Register.js
import React, { useState } from 'react';
import Axios from 'axios';
import {
StyleSheet,
SafeAreaView,
View,
Text,
TouchableOpacity,
TextInput,
} from 'react-native';
import { ScrollView } from 'react-native-gesture-handler';
export default function Register({ navigation }) {
const [nom, setNom] = useState();
const [prenom, setPrenom] = useState();
const [username, setUsername] = useState();
const [matricule, setMatricule] = useState();
const [specialite, setSpecialite] = useState();
const [email, setEmail] = useState();
const [password, setPassword] = useState();
function save() {
console.log({
"matricule": matricule,
"nom": nom,
"prenom": prenom,
"username": username,
"specialite": specialite,
"email": email,
"password": password
})
Axios.post("http://192.168.1.1:8080/api/save",{
'matricule': matricule,
'nom': nom,
'prenom': prenom,
'username': username,
'specialite': specialite,
'email': email,
'password': password
},
{
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}
)
.then(res => console.log(res.data))
alert("User Registation Successfully");
navigation.replace('Login');
}
I see the alert and it navigates to another screen, and returns the data i entered correctly, but it's like it ignores the post request.
Any help would be appreciated.
Thanks
You're invoking an asynchronous operation and then, before any result has been received, immediately notifying the user that the operation succeeded (which you don't know) and immediately navigating away (which I expect could very well just abandon the asynchronous operation).
Perform these tasks in response to the asynchronous operation, not while it's still executing:
.then(res => {
console.log(res.data);
alert("User Registation Successfully");
navigation.replace('Login');
});
Related
I have been following the tinder 2.0 react native tutorial https://youtu.be/qJaFIGjyRms At 1:04:00 he sets the sign in method to: "await Google.logInAsync()" but I have noticed the google app auth library used in the video is now deprecated, I am redirected to use expo auth session instead, with this new library I cannot tell whether the google sign in is working or not as I am simply redirected back to the homepage after clicking the login button.
Here is my code with response printed in the console:
Screenshot:
code:
import React, { createContext, useContext } from 'react'
import * as WebBrowser from "expo-web-browser";
import { Button } from "react-native";
import * as Google from "expo-auth-session/providers/google";
import { useEffect, useState } from "react";
import { useNavigation } from "#react-navigation/native";
import { GoogleAuthProvider, signInWithCredential } from 'firebase/auth';
const AuthContext = createContext({});
const user = null
WebBrowser.maybeCompleteAuthSession();
const GoogleLogin = () => {
const navigation = useNavigation();
const [request, response, promptAsync] = Google.useAuthRequest({
expoClientId:
"236293699216-bst43767un873mcddmmrpgf4v2h088jd.apps.googleusercontent.com",
iosClientId:
"236293699216-6jdpm0rd6kn5d0qlbh1vgva5afgbqgib.apps.googleusercontent.com",
webClientId:
"236293699216-9a0nknjdq7ie79h40iubg0tddokgogfv.apps.googleusercontent.com",
scopes: ["profile", "email"],
permissions: ["public_profile","email", "gender", "location"],
});
const asyncAuthRequest = async () => {
if (response?.type === "success") {
const { authentication } = response;
// await AsyncStorage.setItem("accessTocken", "hihi");
//navigation.navigate"Home");
const { idToken, accessToken} = response;
const credential = GoogleAuthProvider.credential(idToken, accessToken);
await signInWithCredential(auth, credential)
}
return Promise.reject();
};
useEffect(() => {
asyncAuthRequest();
}, [response]);
console.log('response', response)
return (
<Button
disabled={!request}
title="Login"
onPress={() => {
promptAsync();
}}
/>
);
};
export default GoogleLogin;
im using react native expo and push notification works fine when app is running or in background but with the app is close. it doesnt call the method to handle the notification. I need to redirect to detail page. I tried to use function compoents and class components, tried to migrade to legacy notification and the new one.
import React, {useState, useEffect, useRef} from 'react';
import {
Image, ScrollView,
StyleSheet, Text, TouchableOpacity, Platform,
View, Linking,
} from 'react-native';
import * as Notifications from "expo-notifications";
const HomeScreen = (props) => {
useEffect(() => {
notificationListener.current = Notifications.addNotificationReceivedListener(notification => {
const {request, date} = notification ||{}
const {content} = request ||{}
const {data} = content ||{}
const {annKey,type} = data ||{}
if(annKey) {
// navigation.navigate('Detail', {annKey, updateFeed: true, onSelect},)
}
});
responseListener.current = Notifications.addNotificationResponseReceivedListener(response => {
const {notification} = response ||{}
console.log(notification);
const {request, date} = notification ||{}
const {content} = request ||{}
const {data} = content ||{}
const {annKey, type} = data ||{}
if(annKey){
navigation.navigate('Detail', {annKey, updateFeed: true, onSelect},)
}
});
return () => {
Notifications.removeNotificationSubscription(notificationListener);
Notifications.removeNotificationSubscription(responseListener);
};
}, []);
}
export default HomeScreen;
The problem is that the useEffect() get called too late after the app has finished initializing. Therefore the listener is not added before the system has abandoned the notification, and the handler not called.
Fortunately, since you are using the new expo-notifications library, it introduced the useLastNotificationResponse() React hook. It can replace the addNotificationResponseReceivedListener() listener and returns the last notification the user interacted with (i.e. tap). It can be safely used in a useEffect() hook.
You can find the documentation here : https://docs.expo.io/versions/latest/sdk/notifications/#uselastnotificationresponse-undefined--notificationresponse--null
Here is how to use it (it's better to implement it on your root component):
import * as Notifications from 'expo-notifications';
export default function App() {
const lastNotificationResponse = Notifications.useLastNotificationResponse();
React.useEffect(() => {
if (
lastNotificationResponse &&
lastNotificationResponse.notification.request.content.data['someDataToCheck'] &&
lastNotificationResponse.actionIdentifier === Notifications.DEFAULT_ACTION_IDENTIFIER
) {
// navigate to your desired screen
}
}, [lastNotificationResponse]);
return (
/*
* your app
*/
);
}
You have to add this to your app.json file:
"android": {
"useNextNotificationsApi": true,
},
i'm trying to navigate from once a user inputs their Credit card details and presses to the pay button, it takes them to another screen within my app. I've set the navigation path to a screen called products. However my payment function takes the payment via Stripe but doesn't navigate to the next screen.what am i doing wrong?
Here is my payment function
import React, { useState } from 'react'
import { Image, Text, TextInput, TouchableOpacity, View,ImageBackground } from 'react-native'
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view';
import styles from './styles';
import stripe from 'tipsi-stripe';
import axios from 'axios'
stripe.setOptions({
publishableKey:
'pk_test_XXXXX'
})
export default function PaymentScreen({navigation}) {
const [ccNumber, setCCNumber] = useState('')
const [expDate, setExpDate] = useState('')
const [zipCode, setZipCode] = useState('')
const [cvv, setCvv] = useState('')
const [ loading, setLoading] = useState(false)
const [token, setToken] = useState(null)
const onPaymentPress = async () => {
if ( ccNumber && expDate && zipCode && cvv == null) {
alert("All fields must be completed")
return
};
const token = await stripe.paymentRequestWithCardForm({
smsAutofillDisabled: true,
requiredBillingAddressFields: 'full',
prefilledInformation: {
billingAddress: {
name: 'Gunilla Haugeh',
line1: 'Canary Place',
line2: '3',
city: 'Macon',
state: 'Georgia',
country: 'US',
postalCode: '31217',
email: 'ghaugeh0#printfriendly.com',
},
},
})
axios({
method:'POST',
url: 'https://us-central1-lvc2-73300.cloudfunctions.net/completePaymentWithStripe',
data: {
amount: 50000,
currency:'usd',
token: token
},
})
.then(response => {
console.log(response);
loading:false
})
navigation.navigate('Products',{token})
}
here is my on press function to activate the payment
<TouchableOpacity
style={styles.button}
onPress={() => onPaymentPress()}>
<Text style={styles.buttonTitle}>Submit Payment</Text>
</TouchableOpacity>
also i'm using firebase to store the data
Here is my database firebase backend
const stripe = require('stripe')('sk_test_XXXX)
exports.completePaymentWithStripe = functions.https.onRequest(
(request,response) => {
stripe.charges.create({
amount: request.body.amount,
currency: request.body.currency,
source: request.body.token.tokenId,
})
.then(charge => {
response.send(charge)
return null
})
.catch(error => {
console.log(error)
})
}
)
I'm building a code to check if access_token or refresh_token are valid. I'm using axios interceptors to check the response to generate new token.
How to use navigate(React Navigation) inside axios interceptors?
Error:
09:53:55.852 client_log FarmsList:React.FC -> error [Error: Invalid
hook call. Hooks can only be called inside of the body of a function
component. This could happen for one of the following reasons
axios.interceptors.response.use(
(response) => {
return response
},
async (error) => {
const navigation = useNavigation()
const originalRequest = error.config
const accessToken = await getAccessToken()
const refreshToken = await getRefreshToken()
if (
error.response.status === 400 &&
originalRequest.url === connectTokenUrl &&
accessToken
) {
removeConnectToken()
navigation.navigate('SignIn')
return Promise.reject(error)
}
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true
console.log('entrou 401')
if (!refreshToken) {
navigation.navigate('SignIn')
return Promise.reject(error)
}
const data = {
grant_type: 'refresh_token',
client_id: 'xxx',
refresh_token: refreshToken,
}
const formData = new FormData()
_.forEach(data, (value, key) => {
formData.append(key, value)
})
return axios({
method: 'post',
url: connectTokenUrl,
data: formData,
headers: {'Content-Type': 'multipart/form-data'},
}).then((response) => {
const {access_token, refresh_token} = response.data
connectToken(access_token, refresh_token)
axios.defaults.headers.common.Authorization = `Bearer ${accessToken}`
return axios(originalRequest)
})
}
return Promise.reject(error)
},
)
There are several ways to access the navigation props outside the navigation.
The useNavigation hook : this is used for scenarios where you access the navigation prop from functional components which are under the navigation container. Eg : A navigation button which is inside a screen.
The navigationRef : this is used for scenarios where you access the navigation outside the navigation, used for scenarios like redux middleware.
You should use the navgation ref for this scenario and perform your navigation actions. You can use the RootNavigation.js and call the navigation actions.
import { NavigationContainer } from '#react-navigation/native';
import { navigationRef } from './RootNavigation';
export default function App() {
return (
<NavigationContainer ref={navigationRef}>{/* ... */}</NavigationContainer>
);
}
// RootNavigation.js
import * as React from 'react';
export const navigationRef = React.createRef();
export function navigate(name, params) {
navigationRef.current?.navigate(name, params);
}
where is your navigation param? if you can show me more of your code (your full component) will be helpful, its possible that you are calling some hook outside of your functional component
First you have to create a createNavigationContainerRef and a navigate function like this:
// RootNavigation.js
import { createNavigationContainerRef } from '#react-navigation/native';
export const navigationRef = createNavigationContainerRef()
export function navigate(name, params) {
if (navigationRef.isReady()) {
navigationRef.navigate(name, params);
}
}
Then add the newly created navigationRef to the NavigationContainer wrapper:
import { NavigationContainer } from '#react-navigation/native';
import { navigationRef } from './RootNavigation';
export default function App() {
return (
<NavigationContainer ref={navigationRef}>{/* ... */}</NavigationContainer>
);
}
You can now import the navigate function to any .js file and use it. Hope this was useful. For further reference, refer this article.
I am trying to creat an app and in the current module, I need to get the list of productList from redux store. But when I try to read from the store the entire component started an infinit loop. If I comment the below line, everything becomes normal. I am new to React Native and I don't know what I am doing wrong here
const vendorProducts = useSelector(store => store.productList.loadedProducts);
import React, {useState, useEffect} from 'react';
import {View, Text, StyleSheet, TouchableOpacity, FlatList} from 'react-native';
import {useDispatch, useSelector} from 'react-redux';
import * as productListAction from '../store/actions/products';
import Constants from '../constants/constants';
const Products = props => {
console.log('Hello');
const token = useSelector(store => store.auth.token);
//const vendorProducts = useSelector(store => store.productList.loadedProducts);
const dispatch = useDispatch();
useEffect(() => {
async function getProductList() {
let response;
let productList;
try {
const BASEURL = Constants.BASE_URL;
response = await fetch(BASEURL + 'wp-json/wcfmmp/v1/products/', {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: 'Bearer ' + token,
},
});
productList = await response.json();
} catch (error) {
console.error(error);
}
dispatch(productListAction.loadedProducts(productList));
}
getProductList();
});
return (
<View>
<Text>Product</Text>
</View>
);
};
const style = StyleSheet.create({});
export default Products;