How to Fetch Data from Firebase Realtime Database in React Native App - json

How can I fetch data from Firebase Realtime Database using the below method?
My Realtime Database:
import React, { useEffect, useState, useContext, } from 'react';
import { View, Text, Image, StyleSheet, ScrollView, SafeAreaView, ActivityIndicator, FlatList, } from 'react-native';
import {firebase} from '../config';
export default function App() {
const [users, setUsers] = useState([]);
const todoRef = firebase.firestore().collection('testing');
useEffect(() => {
todoRef.onSnapshot(
querySnapshot => {
const users = []
querySnapshot.forEach((doc) => {
const { one, two, three, four
} = doc.data()
users.push({
id: doc.id,
one, two, three, four
})
})
setUsers(users)
}
)
}, [])
return (
<View style={{ backgroundColor: theme.viewOne, }}>
{isLoading ? <ActivityIndicator /> : (
<FlatList
ListHeaderComponent={
<Image source={require('./AllImage/qq2.jpg')}
style={{ width: "auto", height: 150, resizeMode: "cover", }} />
}
data={data}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => (
<View style={styles.container}>
<View style={styles.item}>
<Text style={styles.mainText}>{item.one}</Text>
</View>
<View style={styles.item}>
<Text style={styles.mainText}>{item.two}</Text>
</View>
</View>
)}
/>
)}
</View>
);
};

Rahul for react-native you can implement it like this instead of using async-await.
You need to connect your app to database like this -
import { firebase } from '#react-native-firebase/database';
const reference = firebase
.app()
.database('https://<databaseName>.<region>.firebasedatabase.app/')
.ref('/users/123');
Then you can perform read-write transactions like this -
import database from '#react-native-firebase/database';
database()
.ref('/users/123')
.once('value')
.then(snapshot => {
console.log('User data: ', snapshot.val());
});
The article has a detailed implementation and you can choose to persist data easily as well. Hope it helps!

Related

show a list of data in react native app from sql server

I wanted to show a list of data in my app, I already have backend API that can get the data from the server but when I trying to make it appear in my react native app, it wont appear. Below is the data that get from API
here is the code for show the data in a list view in react native apps
import React, { useState, useEffect,Component,onMount} from 'react';
import {View,Text, Button, StyleSheet,TextInput,ListView,ActivityIndicator,Platform} from 'react-native';
import {useNavigation} from'#react-navigation/native';
import {StatusBar} from'expo-status-bar';
export default function StopJob(){
const[isLoading,setIsLoading]=useState(true);
useEffect(()=>{
return fetch('http://localhost/api/findid.php',{
mode:'no-cors'
})
.then((response) => response.json())
.then((responseJson) => {
let ds = new ListView.DataSource({rowHasChanged: (r1, r2)=> r1 !== r2});
this.setState({
isLoading: false,
dataSource: ds.cloneWithRows(responseJson),
}, function() {
// In this block you can do something with new state.
});
})
.catch((error) => {
console.error(error);
})
},[]);
const Showlist=(user,job,jobid,machinecode,startTime)=>{
this.props.navigation.navigate('Third', {
Userid : user,
Job : job,
JobId : jobid,
MachineCode : machinecode,
StartTime : startTime
});
}
const ListViewItemSeparator = () => {
return (
<View
style={{
height: .5,
width: "100%",
backgroundColor: "#000",
}}
/>
);
}
if(isLoading)return(<View style={{flex: 1, paddingTop: 20}}><ActivityIndicator /> </View>);
return(
<View style={styles.MainContainer_For_Show_StudentList_Activity}>
<ListView
dataSource={this.state.dataSource}
renderSeparator= {this.ListViewItemSeparator}
renderRow={ (rowData) => <Text style={styles.rowViewContainer}
onPress={this.Showlist.bind(
this, rowData.user,
rowData.job,
rowData.jobid,
rowData.machinecode,
rowData.startTime
)} >
{rowData.job}
</Text> }
/>
</View>
);
}
const styles = StyleSheet.create({
MainContainer_For_Show_StudentList_Activity :{
flex:1,
paddingTop: (Platform.OS == 'ios') ? 20 : 0,
marginLeft: 5,
marginRight: 5
},
rowViewContainer: {
fontSize: 20,
paddingRight: 10,
paddingTop: 10,
paddingBottom: 10,
}
});
the expected output will only show the job from the database, but for now the function did not show the list view the error shown Text strings must be rendered within a component.
I was referring this webpage to implement the code : https://reactnativecode.com/insert-update-display-delete-crud-operations/
on the example it show function well but when I try to implement it, it cant work :(
updated but still having same error
export default function StopJob(){
const[isLoading,setIsLoading]=useState(true);
const[dataSource,setdataSource]=useState();
useEffect(()=>{
return fetch('http://localhost/api/findid.php')
.then((response) => response.json())
.then((responseJson) => {
let ds = new FlatList.DataSource({rowHasChanged: (r1, r2)=> r1 !== r2});
setIsLoading(false)
setdataSource(ds.cloneWithRows(responseJson))
})
.catch((error) => {
console.error(error);
})
},[]);
const Showlist=(user,job,jobid,machinecode,startTime)=>{
this.props.navigation.navigate('', {
Userid : user,
Job : job,
JobId : jobid,
MachineCode : machinecode,
StartTime : startTime
});
}
const ListViewItemSeparator = () => {
return (
<View
style={{
height: .5,
width: "100%",
backgroundColor: "#000",
}}
/>
);
}
if(isLoading)return(<View style={{flex: 1, paddingTop: 20}}><ActivityIndicator /> </View>);
return(
<View style={styles.MainContainer_For_Show_StudentList_Activity}>
<FlatList
dataSource={dataSource}
keyExtractor={item=>item.user}
ItemSeparatorComponent= {ListViewItemSeparator()}
renderItem={ (item) => <Text style={styles.rowViewContainer}>{item.job}</Text> }
/>
</View>
);
}
Ok here are the steps to follow:
Use flatlist
Your data source should be a regular array. So, you can use the response from your api as it is.
renderRow should change as renderItem
renderSeparator should change as ItemSeparatorComponent
here is the final form:
const[isLoading,setIsLoading]=useState(true);
const [data, setData]=useState([]);
.......
fetch('http://localhost/api/findid.php',{
mode:'no-cors'
})
.then((response) => response.json())
.then((responseJson) => {
//you can't use setState inside function components. :)
setData(responseJson);
setLoading(false);
})
.catch((error) => {
console.error(error);
})
.......
<FlatList
data={data}
keyExtractor={item => item.jobid} //it should be unique. change it
renderItem={({item}) => <Text>{item.job}</Text>}
/>
This should solve your issue for now but keep in mind these too:
Looks like you don't know differences between class components and function components. Do your research
Flatlist has it's own performance configurations. Research and implement them.

How to connect React native form to express backend

I have created a form to submit some data in react native. Now I need to connect it existing express backend. Help me to do that. I'm a beginner to react native. The following code is the backend. Now I need to submit product id and the description to the SQL server using express backend. How can I do this. my express backend can't be change. changes should be only occur in react native code which I mentioned in the bottom of this text.
router.post('/lodge-complaint', verifyToken, verifyCustomer, async (request, response) => {
const pool = await poolPromise;
try {
pool.request()
.input('_customerEmail', sql.VarChar(50), request.payload.username)
.input('_productID', sql.Int, request.body.productID)
.input('_description', sql.VarChar(5000), request.body.productID)
.execute('lodgeComplaint', (error, result) => {
if (error) {
response.status(500).send({
status: false
});
} else {
console.log(JSON.stringify(result) + ' 75 admin.js');
response.status(200).send({
status: true
});
}
});
} catch (e) {
response.status(500).send({status: false});
}
});
And My react native form is:
import * as React from 'react';
import {Button, View, Text, ScrollView, StyleSheet} from 'react-native';
import {Appbar} from 'react-native-paper';
import {TextInput, HelperText} from 'react-native-paper';
import {useState , useEffect} from 'react';
import Axios from 'axios';
import {complaintSubmission} from '../../services/complaint-submissionService';
const ComplaintSubmission = ({navigation}) => {
const [productID , setproductID] = useState("")
const [complaintSubject , setcomplaintSubject] = useState("")
const [description , setdescription] = useState("")
return (
<ScrollView>
<Appbar.Header>
<Appbar.BackAction onPress={() => navigation.openDrawer()} />
<Appbar.Content title="Submit Complaint" />
<Appbar.Action icon="magnify" onPress={() => navigation.openDrawer()} />
</Appbar.Header>
<Text>Plese Fill the following</Text>
<View>
<TextInput
style={styles.PIDstyle}
label="Product ID"
onChange={ (e) =>{
setproductID(e.target.value)
}}
// value={text}
/>
<HelperText type="error">
{/*<HelperText type="error" visible={hasErrors()}>*/}
Product ID Required
</HelperText>
</View>
<TextInput
style={styles.PIDstyle}
label="Description"
onChange={ (e) =>{
setdescription(e.target.value)
}}
// value={text}
/>
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text>This is submittion</Text>
<Button onPress={() => } title="Submit Complaint" />
</View>
</ScrollView>
);
};
export default ComplaintSubmission;
const styles = StyleSheet.create({
PIDstyle: {
marginTop: 30,
marginLeft: 10,
marginRight: 10,
},
});
What is the function I need to implement in React native code.
Create a new function inside your component, something like handleSubmit() and inside use axios (or fetch) to send the information to the backend, that new function should be called here <Button onPress={() => handleSubmit()} title="Submit Complaint" />.
Please see this tutorial for axios: https://blog.logrocket.com/how-to-make-http-requests-like-a-pro-with-axios/
The function should be like:
const handleSubmit = async () => {
const response = await axios({
method: 'post',
url: '/login',
data: JSON.stringify({
complainid: complainid,
Description: description
}));
// Handle the response
}

Handling JSON response React Native

I'm following the React Native documentation for fetching JSON from an API (https://reactnative.dev/docs/network). I'm new to react and wanting to fetch a wordpress list of posts through its API, but the example they use is very simple and structured differently to how the object is returned from WP.
The problem I'm having is that it is returning the JSON, but I'm unsure how to reference each item I want to display in my flatlist. The line of problem is;
.then((json) => setData(json.movies))
For this WP returned JSON, there is no movies (obviously), in the absence of a referable point what would I specify instead?
My code;
import React, { useEffect, useState } from 'react';
import { ActivityIndicator, FlatList, Text, View } from 'react-native';
export default App = () => {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
useEffect(() => {
fetch('https://public-api.wordpress.com/wp/v2/sites/derbyfutsal.com/posts')
.then((response) => response.json())
.then((json) => setData(json.movies))
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}, []);
return (
<View style={{ flex: 1, padding: 24 }}>
{isLoading ? <ActivityIndicator/> : (
<FlatList
data={data}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => (
<Text>{item.title}, {item.excerpt}</Text>
)}
/>
)}
</View>
);
};
You dont have to specify anything, you can directly set the response to the state value and use it in the flatlist.
I've updated the code to display the id instead of title as its an object. You can change it anyway you want and use it.
const App = () => {
const [isLoading, setLoading] = useState(true);
const [data, setData] = useState([]);
useEffect(() => {
fetch('https://public-api.wordpress.com/wp/v2/sites/derbyfutsal.com/posts')
.then((response) => response.json())
.then((json) => {
setData(json)
})
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}, []);
return (
<View style={{ flex: 1, padding: 24 }}>
{isLoading ? <ActivityIndicator/> : (
<FlatList
data={data}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => (
<Text>{item.id}</Text>
)}
/>
)}
</View>
);
};

How can i solve uniqe key prop problem in React native

I have React Native project and when i try to build my phone, i'm getting this error message. Warning: Each child in an array or iterator should have a unique "key" prop. But it works on computer emulator.
Here is json data: http://hazir.net/api/match/today
and here is my codes,
import React from 'react';
import { FlatList, ActivityIndicator, Text, View } from 'react-native';
export default class Matches extends React.Component {
constructor(props){
super(props);
this.state ={ isLoading: true}
}
componentDidMount(){
return fetch('http://hazir.net/api/match/today')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson,
}, function(){
});
})
.catch((error) =>{
console.error(error);
});
}
render(){
if(this.state.isLoading){
return(
<View style={{flex: 1, padding: 20}}>
<ActivityIndicator/>
</View>
)
}
return(
<View style={{flex: 1, paddingTop:20}}>
<FlatList
data={this.state.dataSource}
renderItem={({item}) => <Text>{item.matchId}, {item.matchDate}</Text>}
keyExtractor={({id}, index) => id}
/>
</View>
);
}
}
The easiest solution would be to update your keyExtractor as it appears to not be working. It doesn't look like your data has an id property, however it does have a matchId property. This means you could do something like the following.
<FlatList
...
keyExtractor={({matchId}, index) => matchId.toString()}
/>
Alternatively you could use the index as the key and do this
<FlatList
...
keyExtractor={({matchId}, index) => index.toString()}
/>

Why can't I display my items in Flatlist?

I am currently trying to learn React-Native atm and I am having some trouble displaying out my items in my FlatList.
The below is my code
import React from 'react';
import { FlatList, ActivityIndicator, Text, View } from 'react-native';
export default class FetchExample extends React.Component {
constructor(props){
super(props);
this.state = {
isLoading: true,
dataSource: []
}
}
componentDidMount(){
return fetch('https://api.coindesk.com/v1/bpi/currentprice.json')
.then((res) => res.json())
.then((resJson) => {
console.log('Here are the stuff', resJson.bpi)
this.setState({
isLoading: false,
dataSource: resJson.bpi,
})
})
// catch any potential errors here
.catch((error) =>{
console.log(error)
})
}
render(){
if(this.state.isLoading){
return(
<View style={{flex: 1, padding: 20}}>
<ActivityIndicator />
</View>
);
}
return(
<View style={{flex: 0.5, padding: 20}}>
<Text>{console.log(this.state.dataSource)}</Text>
<Text>Here's some testing text</Text>
<Text>{console.log("This is in this.state.dataSource", this.state.dataSource)}</Text>
{/* <FlatList
data= {this.state.dataSource}
renderItem = {({item}) => <Text>{console.log(item)}</Text>}
/> */}
</View>
)
}
}
Whenever I uncomment the FlatList the simulator will shoot me an error saying "Invariant Violation: Tried to get frame for out of range index NaN"
What am I doing wrong? Atm I am just trying to see what's in item and get an understanding of how to work with Flatlist
here how i do it
<FlatList
data={[this.state.dataSource]}
renderItem={({ item }) => this._renderListItem(item)}
/>
and here the _renderListItem()
_renderListItem(item){
console.log(item)
return(
<View>
<View style={{flexDirection:'row',width:'100%',backgroundColor:'red'}}>
<Text>{item.USD.code}</Text>
<Text>{item.USD.symbol}</Text>
<Text>{item.USD.description}</Text>
</View>
</View>
)
}
and here is the expo link click here you get the idea
and if any questions you have please ask me ...