setState not working properly in release mode React native iOS - android

I'm fetching some data from a server to load it to my app, my app doesn't load until the app loads all the data, it works perfectly in the debug mode, but when I have to test it on release mode, I have to reload it in order to make it work, and that is not the idea. Here's my code:
import React, { Component } from 'react';
import { Alert, NetInfo, View, Text, AsyncStorage, TouchableWithoutFeedback, Linking, Platform } from 'react-native';
import { Actions } from 'react-native-router-flux';
import Router from './Router';
import OnBoarding from './components/OnBoarding';
import Loading from './components/Loading';
import OneSignal from 'react-native-onesignal';
import axios from 'axios';
var DeviceInfo = require('react-native-device-info');
class App extends Component {
constructor(props) {
super(props);
this.state = {
usage: '',
categories_hum: [],
videoshum: [],
categories_nov: [],
novedades: [],
tiendas: [],
promociones: [],
listadoCodigos: [],
token: "",
listadoCodigosRecibido: true,
terminos: '',
notFirst: false
};
this.changeUsage = this.changeUsage.bind(this);
}
onIds(device) {
AsyncStorage.setItem('playerId', device.userId);
}
onOpened(openResult) {
if(openResult.notification.payload.additionalData != undefined) {
var opc = openResult.notification.payload.additionalData.opc;
if(opc == 2) {
opc = "2";
AsyncStorage.setItem('opcion', opc);
} else if(opc == 1) {
opc = "1";
AsyncStorage.setItem('opcion', opc);
}
}
}
componentWillMount() {
OneSignal.addEventListener('ids', this.onIds);
OneSignal.addEventListener('opened', this.onOpened);
}
componentDidMount() {
NetInfo.isConnected.fetch().then(isConnected => {
if(!isConnected) {
Alert.alert (
'No hay conexion',
'No hay conexion a internet, debe poseer una conexion WiFi o celular para usar FerretotalApp'
);
}
});
fetch('https://ferrretotalcom.kinsta.com/wp-json/wp/v2/categoria-hum?per_page=100')
.then(response => response.json())
.then(
response => this.setState({ categories_hum: response})
);
fetch('https://ferrretotalcom.kinsta.com/wp-json/wp/v2/videoshum?per_page=100')
.then(response => response.json())
.then(
response => this.setState({ videoshum: response })
);
fetch('https://ferrretotalcom.kinsta.com/wp-json/wp/v2/tienda_acf?per_page=100')
.then(response => response.json())
.then(
response => this.setState({ tiendas: response })
);
fetch('https://ferrretotalcom.kinsta.com/wp-json/wp/v2/categorianovedades?per_page=100')
.then(response => response.json())
.then(
response => this.setState({ categories_nov: response })
);
fetch('https://ferrretotalcom.kinsta.com/wp-json/wp/v2/ferretotalnovedades?per_page=100')
.then(response => response.json())
.then(
response => this.setState({ novedades: response })
);
fetch('https://ferrretotalcom.kinsta.com/wp-json/wp/v2/promociones_activas?hola=1')
.then(response => response.json())
.then(
response => this.setState({ promociones: response })
);
fetch('https://ferrretotalcom.kinsta.com/wp-json/wp/v2/listado_codigos_usuario?deviceID="'+DeviceInfo.getUniqueID()+'"')
.then(response => response.json())
.then(
response => this.setState({ listadoCodigos: response, listadoCodigosRecibido: true})
);
fetch('https://ferrretotalcom.kinsta.com/wp-json/wp/v2/terminos_condiciones?hola=1')
.then(response => response.json())
.then(
response => this.setState({ terminos: response})
);
AsyncStorage.getItem('usage').then((result) => {
if(!result){
this.setState({usage: "firstTime"});
}else{
this.setState({usage: result});
}
//al colocar esto hara q salga siempre el onboarding
//AsyncStorage.removeItem("usage");
});
AsyncStorage.getItem('notFirst').then((result) => {
if(!result){
this.setState({notFirst: false});
} else {
this.setState({notFirst: false})
}
});
AsyncStorage.getItem('token').then((value) => {
if(!value){
var DeviceID = DeviceInfo.getUniqueID();
fetch('https://ferrretotalcom.kinsta.com/wp-json/wp/v2/recibir_token?deviceID="'+DeviceID+'"')
.then((response) => response.json())
.then((response) => {
if(response[0]){
AsyncStorage.setItem('token',response[0].access_token);
this.setState({token: response[0].access_token});
}
})
} else {
this.setState({token: value})}
});
AsyncStorage.setItem('newCode',"false");
}
componentWillUnmount() {
OneSignal.removeEventListener('ids', this.onIds);
OneSignal.removeEventListener('opened', this.onOpened);
}
changeUsage(e) {
this.setState({usage: "notFirst"});
this.setState({notFirst: true});
}
render(){
/*alert(this.state.categories_hum.length + " " + this.state.videoshum.length + " " + this.state.promociones.length
+ " " + this.state.novedades.length + " " + this.state.categories_nov.length + " " + this.state.tiendas.length + " " + this.state.listadoCodigosRecibido + " " + this.state.terminos.length) */
if(this.state.categories_hum.length && this.state.videoshum.length && this.state.promociones.length
&& this.state.novedades.length && this.state.categories_nov.length && this.state.tiendas.length && this.state.listadoCodigosRecibido && this.state.terminos.length) {
if(this.state.usage.length && this.state.usage == "firstTime"){
//al colocar esto solo saldra el onboarding la primera vez
AsyncStorage.setItem('usage', "notFirst");
AsyncStorage.setItem('notFirst', true)
//al colocar esto, guardara la fecha de instalacion de la aplicacion (realmente la primera vez que se mete)
AsyncStorage.getItem('installed').then((result) => {
if(!result) {
var date = new Date();
date = date.toString();
AsyncStorage.setItem('installed', date);
}
});
return (
<OnBoarding changeUsage={this.changeUsage} terminos={this.state.terminos}/>
);
} else if(this.state.usage == "notFirst" && this.state.notFirst == false) {
return(
<OnBoarding changeUsage={this.changeUsage} terminos={this.state.terminos} notFirst={true}/>
);
} else if(this.state.usage == "notFirst" && this.state.notFirst) {
return (
<View style={{flex:1}}>
<Router
categories_hum={this.state.categories_hum}
videoshum={this.state.videoshum}
categories_nov={this.state.categories_nov}
novedades={this.state.novedades}
tiendas={this.state.tiendas}
listadoCodigos={this.state.listadoCodigos}
promociones={this.state.promociones}
token={this.state.token}
terminos={this.state.terminos}
/>
</View>
);
}
} else{
return (
<Loading/>
)
}
}
}
export default App;
As you can see, I'm fetching all the data I need in the "ComponentDidMount" method, then I store the JSON data in multiple states and pass it to the screens I need, the thing is that in release mode, the states don't have anything after it "loads" and it only happens the first time you open the app and only in release mode, I check the response from fetch and it is ok, it brings the data. I have tried lot of things but I can't still figured out what it is since it works well in debug mode. Please if you have any ideas, you can tell me.

From the description , it seems the task is not being synchronous with expected behavior.
setState is asynchronous by default but in my experience I have known some cases where I have to make it explicitly asynchronous using "Async" and "await".
I am not sure but It might be a work around for you too in every setState invoking methods as belows:
async changeUsage(e) {
await this.setState({usage: "notFirst"});
await this.setState({notFirst: true});
}

Related

react-native-ble-plx HELP to get the Service and Characteristics and to WriteWithoutResponse

I'm new on Ble-Plx and React-Native, I'm working on a project where we should be able to connect to a device and change the behavior, just writing new characteristics and it should change... I used a Ble Starter that I found on the internet, and I was able to write the characteristics and change the behavior. So I know the peripheral can do it and that I only need to develop the code. I have something already but when I write the characteristics the device doesn't change as we spect, the device does NOTHING and I don't get any error or something Just the device does nothing. Here is a piece of code if someone can help would be amazing!
HERE IS THE MAIN PART OF THE CODE:
import { BleManager } from 'react-native-ble-plx';
const manager = new BleManager();
const Example=()=>{
useEffect(() => {
manager.onStateChange((state) => {
const subscription = manager.onStateChange((state) => {
if (state === 'PoweredOn') {
scanAndConnect();
subscription.remove();
}
}, true);
return () => subscription.remove();
});
}, [manager])
function scanAndConnect() {
console.log('Escanear')
manager.startDeviceScan(null,null,async(error,device)=>{
console.log(device.id)
if(device.id ==='D1:42:78:C8:AB:FB' || device.id ==='D1:42:BF:F1:D9:3C'){
manager.stopDeviceScan()
console.log("ID del dispositivo: ", device.id)
console.log("Nombre del dispositivo: ", device.name)
console.log("RRSI del dispositivo: ", device.rssi)
console.log("MTU del dispositivo: ", device.mtu)
device.connect()
.then((device) => {
const services = device.discoverAllServicesAndCharacteristics()
console.log(services)
})
.catch((error) => {
// Handle errors
console.log(error)
});
}
if (error) {
console.log(error)
return
}
})
}
const writeChar=async()=> {
var text = (Buffer.from("AA0100000200").toString('base64'));
manager.writeCharacteristicWithoutResponseForDevice(
'D1:42:BF:F1:D9:3C',
'aae0',
'aae1',
text,
)
.then(() => {
console.log("Write: " + text);
})
.catch((error) => {
console.log(error);
});
}
AND HERE IS WHAT THE CONSOLE.LOG GIVE ME BACK.
D1:42:BF:F1:D9:3C
LOG ID del dispositivo: D1:42:BF:F1:D9:3C
LOG Nombre del dispositivo: Bluetrum-MX
LOG RRSI del dispositivo: -73
LOG MTU del dispositivo: 23
LOG {"_U": 0, "_V": 0, "_W": null, "_X": null}
LOG Write: QUEwMTAwMDAwMjAw
BUT even that there is no error the device doesn't change so there is my problem, I'm NOT able to make the device change the behavior and start the vibration (just by writing the characteristics)
Put await before manager while writing characteristics
and try below code
const writeChar=async()=> {
var text = (Buffer.from("AA0100000200").toString('base64'));
await manager.writeCharacteristicWithoutResponseForDevice(
'D1:42:BF:F1:D9:3C',
'aae0',
'aae1',
text,
)
.then((res) => {
console.log("Write: " + text);
console.log("res",res)
})
.catch((error) => {
console.log(error);
});
}

can't produce downloadable link from firebase storage

I am developing a React native app. I am uploading a batch of images using react-native-image-crop-picker. Using the way that storing the path in an array and one by one uploading the image. but I can't produce the downloadable link for the uploaded files. I am getting 2 errors
1)Can not read property 'then' of undefined
2)when trying to get the downloadable link it cannot find the object
below is my code
AddProduct = () => {
this.setState({ loading: true })
this.setState({ disabled: true })
//-------------UUIDGenerator-------------
UUIDGenerator.getRandomUUID().then((productUid) => {
this.setState({ productUid });
() => console.log("setted state=" + this.state.productUid)
console.log("Generated UUid " + this.state.productUid)
});
//----------------------------------------
//image upload
try {
setTimeout(() => {
const fs = RNFetchBlob.fs
const uid = "flyers/" + this.state.productUid;
const imageRef = firebase.storage().ref(uid).child('abc' + ".jpg") //string "dp1.jpg"
let mime = 'image/jpg'
if (this.state.imagePath === "") {
alert("Select a Flyer")
return
}
//-----------------Checking Inputs-----------
if (this.state.title.length < 1) {
alert("Enter a Title");
return;
}
if (this.state.description.length < 3) {
alert("Enter At least 3 words To describe the product ")
return;
}
if (this.state.storename.length < 1) {
alert("Enter a Storename")
return;
}
alert("Uploading Flyer" + this.state.title)
//------------------------------------------------
this.state.imagePath.forEach((data) => {
// coverting to base64
new Promise((resolve, reject) => {
fs.readFile(data, 'base64')
.then((data) => {
return Blob.build(data, { type: `${mime};BASE64` })
})
.then((blob) => {
console.log("blob " +JSON.stringify(blob))
//uplaoding Image
uploadBlob = blob
name =name + 1
firebase.storage().ref(uid).child(name + ".jpg").put(blob) // ,{ contentType: mime }
})
.then(() => {
//uploadBlob.close()
//getting url
console.log("1")
return firebase.storage().ref(uid).child(name + ".jpg").getDownloadURL()
})
})
})
.then(() => {
//urls = url;
console.log('urls=' + urls)
//================================
try {
alert("Uploading Flyerss" + this.state.title)
//-------------------------------------------
//----------Inserting Data to Database--------
usersTable = 'flyers/' + this.state.productUid,
console.log(usersTable)
firebase.database().ref(usersTable).set(
{
title: this.state.title,
description: this.state.description,
imageUrls: this.state.imageUrls,
storename: this.state.storename,
user: asyncValue,
longitude: this.state.longitude,
latitutde: this.state.latitutde
}
).then(
console.log("then"),
this.title.clear(),
this.description.clear(),
//this.category.clear(),
this.setState({ loading: false }),
this.setState({ disabled: false }),
this.setState({ title: "" }),
this.setState({ storename: "" }),
this.setState({ description: "" }),
this.setState({ imagePath: "" }),
urls = "",
alert(this.state.title + " flyer sucessfully uploaded")
)
//--------------------------------------------
}
catch (error) {
this.setState({ loading: false })
this.setState({ disabled: false })
console.log(error.toString())
alert(error.toString())
}
//================================
})
}, 3000)
}
catch (error) {
console.log("upload Error = " + error)
}
}

Infinite scroll not working in Listview React Native

i want pagination in my react native application so below is my code
<ListView bounces={false}
enableEmptySections={ true }
automaticallyAdjustContentInsets={ false }
dataSource={this.state.dataSourceRadio}
renderRow={(rowData, sectionID, rowID) => this.renderSiteView(rowData, rowID)}
onEndReached={this.onEndReached}
/>
onEndReached() {
if (!this.state.waiting) {
this.state.offset=10,
this.APIGetSiteGPS(this.state.token);
}
}
When i run above code next page data not come so any idea how can i solve this? your all suggestion are appreciable
I update my view in this method
_bindingRadioButtonData(data) {
this.setState({
dataSourceRadio: this.state.dataSourceRadio.cloneWithRows(data),
})
}
API call methods
APIGetSiteGPS(token) {
console.log(TAG + "customer Api: " + APPCONSTANTS.BASE_URL + "site" + " " + token)
fetch(APPCONSTANTS.BASE_URL + "site?&offset=" + this.state.offset, {
method: APPCONSTANTS.API_METHOD.GET,
headers: {
'Accept': APPCONSTANTS.HEADERS.VALUE.ACCEPT,
'Content-Type': APPCONSTANTS.HEADERS.VALUE.CONTENT_TYPE,
'Authorization': 'Bearer ' + token,
},
})
.then(response => {
const statusCode = response.status;
const data = response.json();
// data: offset === 0 ? res.results : [...this.state.siteList, ...res.results];
return Promise.all([statusCode, data]);
})
.then((res, data) => {
this.responseReceive(res)
})
.catch((error) => {
this.stopLoadingIndicator()
console.log('error..', error);
})
}
responseReceive(response) {
this.stopLoadingIndicator()
console.log(TAG + 'Response-->' + JSON.stringify(response));
var temp = this.state.siteList;
if (response[0] == APPCONSTANTS.API_RESPONSE_STATUS.SUCCESS) {
for (let i = 0; i < response[1].data.sites.length; i++) {
temp.push(response[1].data.sites[i]);
}
this.setState({ siteList: temp})
setTimeout(() => {this._bindingRadioButtonData(this.state.siteList)}, 1000)
this.setState({isFirstDataLoad:true});
//this.onEndReached();
} else {
Alert.alert(APPCONSTANTS.APP_NAME, response[1].message)
}
}

React Native - Sending information so as to receive a response for simple login screen but receiving JSON parse error instead

I have tried several times to send the data and receive a response, but it does not seem to be sending the data put in by the user. I have tried going about this in several ways,I will share the code for the last two.
ONE
state = {
phoneNo: '',
pin: '',
isLoggingIn: false,
message: ''
}
_userLogin = () => {
console.log("userLogin");
this.setState({isLoggingIn: true, message:''});
var params = {
phoneNo: this.state.phoneNo,
pin: this.state.pin
};
var proceed = false;
fetch("https://"+"<url>", {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
})
.then(
(response) => response.json())
.then((response) => {
if (response.status == 200) {
proceed = true;
}
else {
this.setState({ message: response.message });
console.log(message); }
})
.then(() => {
this.setState({ isLoggingIn: false })
if (proceed) this.props.onLoginPress();
})
.catch(err => {
console.log(err.message);
this.setState({ message: err.message });
this.setState({ isLoggingIn: false })
});
}
Two
The only difference here is how I am handling the response so I will only add that section. I thought that the issue might be due to syntax at this point.
.then(function(response){
return response.json();
})
.then(function(data){
console.log(data)
I have been through various tutorials, github and stackoverflow pages addressing the issue but I seem to be missing something. I keep getting a JSON parse error and I am convinced that perhaps the data is never being sent to the url because I get the error regardless of user input.
Both input fields have a ref and the button points to the user login function.
<TextInput
ref = {component => this._pin = component}
placeholder="pin"
onChangeText = {(pin) => this.setState({pin})}
secureTextEntry = {true}
onSubmitEditing={this._userLogin}
/>
<TouchableOpacity
onPress={this._userLogin}
title = "Submit"
disabled={this.state.isLoggingIn||!this.state.phoneNo||!this.state.pin}>
<Text style={styles.loginText}>Sign In</Text>
</TouchableOpacity>
try something like this.
I also get problem acceding both status code & data from fetch call, so i made "processResponse" function
processResponse=(response) =>{
const statusCode = response.status;
const data = response.json();
return Promise.all([statusCode, data]).then(res => {
return ({
statusCode: res[0], // the status code
data: res[1] // the data of the GET/POST returned by fetch call
})
}
);
}
_userLogin = () => {
console.log("userLogin");
this.setState({isLoggingIn: true, message:''});
var params = {
phoneNo: this.state.phoneNo,
pin: this.state.pin
};
fetch("https://"+"<url>", {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(params)
})
/*processResponse return both status and data , because when you make
.then((response) => response.json()) you return only data and status is removed
*/
.then(this.processResponse)
.then(res => {
console.log("response of fetch",res);
const { statusCode, data } = res;
if (statusCode > 200) {
this.props.onLoginPress()
}else{
this.setState({ message: data.message });
console.log("data message" , data.message);
}
this.setState({ isLoggingIn: false })
})
.catch(err=> {
console.error(err);
this.setState({ message: err.message});
this.setState({isLoggingIn: false})
});
});
}
AlainIb was very helpful and this helped contribute to what worked in the end. Using form data seemed to assist with the JSON Parse error. Hope this helps anyone else who is having any troubles.
state = {
message: ''
}
_processResponse = (response) =>{
const statusCode = response.status;
console.log("resp", response);
const data = response.json();
console.log("data", data);
return Promise.all([statusCode, data]).then(res => {
return ({
statusCode: res[0], // the status code
data: res[1] // the data of the GET/POST returned by fetch call
})
});
}
_userLogin = () => {
console.log("userLogin");
this.setState({isLoggingIn: true, message:''});
var params = {
phoneno: this.state.phoneno,
pin: this.state.pin
};
var formData = new FormData();
formData.append("phoneno", this.state.phoneno);
formData.append("pin", this.state.pin);
console.log(formData);
let data = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type':'multipart/form-data'
},
body: formData
}
console.log(data);
fetch("https://"+"url", data)
.then(this._processResponse)
.then(res => {
console.log("response of fetch",res);
const { statusCode, data } = res;
if (statusCode == 200) {
console.log("in if statement");
if(data.login_success== 1){
console.log("name to be passed", data.name);
console.log("log in to profile");
this.props.navigation.navigate('ProfileRoute');
}else {
console.log("fail");
this.setState({message:"Password or Phone Number is Wrong"});
}
}else{
this.setState({ message: data.message });
console.log("data message" , data.message);
}
this.setState({ isLoggingIn: false })
})
.catch(err=> {
console.error(err);
this.setState({ message: err.message});
this.setState({isLoggingIn: false})
});
}

Fetch data from fbsdk react native

Hi I have implemented the Facebook login in my react native app. I have not used the standard button that comes with sdk. Everything work fine login is successful. But now I don't know how to extract data from Facebook user profile i.e name, email.
Below is my code
_fbAuth() {
LoginManager.logInWithReadPermissions(['public_profile']).then(function (result) {
if (result.isCancelled) {
console.log('Login was Cancelled');
} else {
const { navigate } = this.props.navigation;
//
console.log('Login Successful' + result.grantedPermissions.toString());
}
}, function (error) {
console.log('An error has occured' + error);
})
}
code for button
<TouchableHighlight onPress={() => { this._fbAuth() }}>
<Image source={require('../images/facebook-logo.png')} style={styles.facebook}></Image>
</TouchableHighlight>
You need to use AccessToken function along with the LoginManager to get the token when login is successful. After receiving the token, we can use this token to retrieve data of logged-in user using graph api of facebook.
Consider the code below:
import { LoginManager, AccessToken } from 'react-native-fbsdk';
async _fbAuth() {
let { isCancelled } = await LoginManager.logInWithReadPermissions(['public_profile','user_posts']);
if ( !isCancelled ) {
let data = await AccessToken.getCurrentAccessToken();
let token = data.accessToken.toString();
await afterLoginComplete(token);
}
else {
console.log('Login incomplete');
}
}
const afterLoginComplete = async (token) => {
const response = await fetch(
`https://graph.facebook.com/me?fields=id,name,first_name,last_name,gender,picture,cover&access_token=${token}`);
let result = await response.json();
// use this result as per the requirement
};
You can learn how to use facebook graph API from here
import {AccessToken,LoginManager} from 'react-native-fbsdk';
fbAuth() {
var current = this;
const { navigate } = this.props.navigation;
LoginManager.setLoginBehavior('web');
LoginManager.logInWithReadPermissions(['public_profile','email']).then(
function (result) {
if (result.isCancelled) {
console.log('Login was cancelled');
}
else {
//var accessToken = null;
AccessToken.getCurrentAccessToken().then(
(data) => {
console.log(data.accessToken.toString())
const{accessToken} = data
// with the help of access token you can get details for fb login
console.log('accessToken: ' + accessToken);
fetch('https://graph.facebook.com/v2.5/me?fields=email,name,friends&access_token=' +accessToken)
.then((response) => response.json())
.then((json) => {
console.log('jsonn: ' + json);
console.log('Login name: ' + json.name);
console.log('Login id: ' + json.id);
console.log('Login email: ' + json.email);
var nsn = json.name
console.log('Login email state: ' +nsn);
var idfb = json.id
console.log('Login email state: ' +idfb);
var idemail = json.email
console.log('Login email state: ' +idemail);
})
.catch(() => {
reject('ERROR GETTING DATA FROM FACEBOOK')
})
})
}
},
function (error) {
console.log('Login failed with error: ' + error);
}
);
}

Categories

Resources