I am learning react-native-push-notifications with react-native-firebase. I want to receive a push notification upon deleting a user. The deletion is working fine. However, taking several tutorials online and doing different things, I am unable to receive notifications. Can somebody guide me how to change this in order to get a push notification as well, upon clicking the "Delete User"? Thanks in advance.
export default class UpdateInfo extends Component {
constructor() {
super();
this.state = {
displayName: '',
email: '',
isLoading: false
}
}
deleteUser = () => {
firebase.auth().currentUser.delete().then(() => {
console.log("The user was deleted successfully")
}).catch(function (error) {
console.error({error})
})
}
render() {
if(this.state.isLoading){
return(
<View>
<ActivityIndicator size="large" color="#9E9E9E"/>
</View>
)
}
return (
<View>
<TouchableOpacity
onPress={() => this.deleteUser()}
>
<Text>DELETE USER</Text>
</TouchableOpacity>
</View>
);
}
}
Related
I'm new to React Native Would like to get any good solution for following task:
Create one application which will call one API
(https://api.napster.com/v2.0/playlists?apikey=ZTk2YjY4MjMtMDAzYy00MTg4LWE2MjYtZDIzNjJmMmM0YTdm).
Using thread and store it in some file.
Current Code
class App extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
dataSource: null,
}
}
componentDidMount() {
return fetch('https://api.napster.com/v2.0/playlists?apikey=ZTk2YjY4MjMtMDAzYy00MTg4LWE2MjYtZDIzNjJmMmM0YTdm')
.then(response => response.json())
.then((responseJSON) => {
this.setState({
isLoading: false,
dataSource: responseJSON.playlists,
})
})
.catch((error) => {
console.log(error);
})
}
render() {
if (this.state.isLoading) {
return (
<View style={styles.container}>
<ActivityIndicator />
</View>
)
} else {
let dbSource = this.state.dataSource.map((val, key) => {
return (
<View key={key} style={styles.item}>
<Text>{val.name}</Text>
</View>
)
})
return (
<View style={styles.container}>
{dbSource}
</View>
);
}
}
};
NetInfo is used to check the connection & theres a checkNetwork function called in onPress of TouchableOpacity. When the button is clicked once, the checkNetwork
function is called automatically multiple times without tapping the button when the network connection is lost and vice versa.
Please have a look at the code here:
Please have a look at the video
export default class App extends React.Component {
checkNetwork = () => {
NetInfo.addEventListener((state) => {
if (state.isConnected) {
alert('isConnected');
} else {
alert('not connected');
}
});
};
render() {
return (
<View style={styles.container}>
<TouchableOpacity
activeOpacity={0.8}
onPress={()=> this.checkNetwork()}>
<Text>Check here</Text>
</TouchableOpacity>
</View>
);
}
}
You should not declare event listener inside of the click itself,
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {alert: ''};
}
componentDidMount() {
NetInfo.addEventListener((state) => this.setState({ alert: state.isConnected ? 'isConnected' : 'not connected'})
}
checkNetwork = () => alert(this.state.alert)
render() {
return (
<View style={styles.container}>
<TouchableOpacity
activeOpacity={0.8}
onPress={()=> this.checkNetwork()}>
<Text>Check here</Text>
</TouchableOpacity>
</View>
);
}
}
though in your case event listener isn't exactly the fit logic for UI behavior of pressing button, so I think you might wanna use useNetInfo
import {useNetInfo} from "#react-native-community/netinfo";
class App extends React.Component {
checkNetwork = () => {
if (this.props.netInfo.isConnected) {
alert('isConnected');
} else {
alert('not connected');
}
});
};
...rest render...
}
export default () => <App netInfo={useNetInfo()} />
class Wait extends Component{
constructor(props) {
super(props);
this.state = { fetchingData: true, data: [], check: ''}
this.forceUpdateHandler.bind(this);
}
getData = async() => {
try {
data = await AsyncStorage.getItem('restaurants');
if (data != null) {
this.setState({fetchingData: false , data: JSON.parse(data)})
}
} catch(error){
console.log(error)
}
}
forceUpdateHandler(){
this.forceUpdate();
};
componentDidMount(){
this.getData();
}
renderRestaurant(){
return this.state.data.map((item) => {
return (
<View style ={{marginTop: 20, backgroundColor: 'red', marginTop: 20 }}>
<Text> {item.name} </Text>
<Text> {item.time} </Text>
<Text> {item.wait} </Text>
<Text> {item.people} </Text>
<Button title = 'cancel' onPress = { async () => {
let data = await AsyncStorage.getItem('restaurants');
let temp = JSON.parse(data)
let i = -1
temp.map((value, index) => {
if (value.name == item.name){
i = index;
}
})
if (i > -1){
temp.splice(i, 1)
await AsyncStorage.setItem('restaurants', JSON.stringify(temp))
}
this.forceUpdateHandler() // First way
this.forceUpdate() // Second way
this.setState({check: 'checked'}) // Third way
}
}
/>
</View>
)
})
}
render(){
const { navigate } = this.props.navigation;
const { navigation } = this.props;
return (
<View style={{width:200, height:200, justifyContent:'center', alignItems:'center', }}>
{this.state.fetchingData ? null : this.renderRestaurant()}
</View>
)
}
}
I am trying to make the page re-render each time after I click the button. Once click the button, it access the AsyncStorage and delete the corresponding element in the array, then it update the AsyncStorage with the new array and re-render the page.
I have tried the following:
1) call forUpdate directly after the update of the AsyncStorage
2) define the forceUpdateHandler function and bind it with this
3) call this.setState after the update of the AsyncStorage
But none of the above options re-renders the page. Can someone help to fix it? An example would be great! Thanks in advance.
The answer is simple. It doesn't re-render because it has nothing to re-render. It calls the render, check each component in the render if the data used to render it has changed and render them if needed. If you look at your code, you see that on the button press, you save in the async storage the new data. However, your rendering uses this.state.data to render the item. The problem is that you never update the state of your component with the new data.
Sure, you do this.setState({check: 'checked'}), but nothing in the render is using it. So there's no point in updating the UI.
An easy way to fix it would be to call this.getData() at the end of the button onPress. That way, you would update the data state which would update your UI.
Get the updated list of restaurants { removing the selected restaurant}
Stored the updated list to Asyncstorage.
fetch the updated list from asyncStorage and set the state.
storeData = async (restaurants) => {
try {
await AsyncStorage.setItem('restaurants', JSON.stringify(restaurants))
} catch (error) {
console.log("Error", error);
}
}
renderRestaurant(){
return this.state.data.map((item, index, restaurants) => {
return (
<View key={index}>
<Text> {item.name} </Text>
<Text> {item.time} </Text>
<Button
title = 'cancel'
onPress = {() => {
let restaurantListWithoutCurrentRestaurant = restaurants.filter((restaurant)=> restaurant.name !== item.name);
this.storeData(restaurantListWithoutCurrentRestaurant);
this.getData();
}}/>
</View>
)
})
}
I think this will solve your problem.
First I want to start by saying I am a total noob at React Native and Shoutem. I am not sure if I should write Shoutem or React Native in the subject of my questions, but here is my problem.
I have two screens:
Screen1.js
Screen2.js
Screen1 displays a list of items returned from a fetch. Once I click on the item, it will open the second screen which is the details screen.
I am passing data from screen1 to screen2. In screen2 I need to make another fetch call for different data, but it does not work. I am doing exactly the same thing on both screens.
Here is my code for Screen1:
import React, {
Component
} from 'react';
import {
ActivityIndicator,
TouchableOpacity
} from 'react-native';
import {
View,
ListView,
Text,
Image,
Tile,
Title,
Subtitle,
Overlay,
Screen
} from '#shoutem/ui';
import {
NavigationBar
} from '#shoutem/ui/navigation';
import {
navigateTo
} from '#shoutem/core/navigation';
import {
ext
} from '../extension';
import {
connect
} from 'react-redux';
export class List extends Component {
constructor(props) {
super(props);
this.renderRow = this.renderRow.bind(this);
this.state = {
isLoading: true,
content: null,
}
}
componentDidMount() {
return fetch('https://www.cannabisreports.com/api/v1.0/strains').then((response) => response.json()).then((responseData) => {
this.setState({
isLoading: false,
content: responseData
});
}).done();
}
renderRow(rowData) {
const { navigateTo } = this.props;
return (
//<Text>{rowData.name}, {rowData.createdAt.datetime}</Text>
<TouchableOpacity onPress={() => navigateTo({
screen: ext('Strain'),
props: { rowData }
})}>
<Image styleName="large-banner" source={{ uri: rowData.image &&
rowData.image ? rowData.image : undefined }}>
<Tile>
<Title>{rowData.name}</Title>
<Subtitle>none</Subtitle>
</Tile>
</Image>
</TouchableOpacity>
);
}
render() {
if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ActivityIndicator />
</View>
);
}
return (
<View style={{flex: 1, paddingTop: 20}}>
<ListView
data={this.state.content.data}
renderRow={rowData => this.renderRow(rowData)}
/>
</View>
);
}
}
// connect screen to redux store
export default connect(
undefined,
{ navigateTo }
)(List);
I am passing rowData to Screen2. I then need to make another fetch calling using data from rowData as it is a path parameter needed for the API call in Screen2.
So basically I need to make a fetch call in Screen2 like this:
fetch('https://mywebsite.com/'+rowData.something+'/myotherdata')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
content: responseJson.data
})
})
.catch((error) => {
console.error(error);
});
Here is my code for screen2:
export default class Strain extends Component {
constructor(props) {
super(props);
this.state = {
content: null,
}
}
componentDidMount() {
return fetch('https://mywebsite.com/'+rowData.something+'/myotherdata')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
content: responseJson.data
})
})
.catch((error) => {
console.error(error);
});
}
renderRow(dataContent) {
return (
<Text>{dataContent.name}</Text>
// This does not work either -> <Text>{dataContent}</Text>
);
}
render() {
const { rowData } = this.props; //This is coming from screen1.js
return (
<ScrollView style = {{marginTop:-70}}>
<Image styleName="large-portrait" source={{ uri: rowData.image &&
rowData.image ? rowData.image : undefined }}>
<Tile>
<Title>{rowData.name}</Title>
<Subtitle>{rowData.createdAt.datetime}</Subtitle>
</Tile>
</Image>
<Row>
<Text>Seed Company: {rowData.seedCompany.name}</Text>
</Row>
<Divider styleName="line" />
<Row>
<Icon name="laptop" />
<View styleName="vertical">
<Subtitle>Visit webpage</Subtitle>
<Text>{rowData.url}</Text>
</View>
<Icon name="right-arrow" />
</Row>
<Divider styleName="line" />
<View style={{flex: 1, paddingTop: 20}}>
<ListView
data={content}
renderRow={dataContent => this.renderRow(dataContent)}
/>
</View>
<Divider styleName="line" />
</ScrollView>
);
}
}
My fetch URL returns data like this:
{
data: {
name: "7.5833",
another_name: "8.6000",
different_name: "5.7500",
}
}
This only returns one data object like what you see above.
When I run the code I get this error:
null is not an object (evaluating 'Object.keys(e[t])')
Please let me know if you need me to provide more info.
I have tried so many different things and nothing seems to work so I am in need of some help. What am I doing wrong?
Not sure why this works but it does.
I used a function to fetch my data and then call the function in componentDidMount like this:
getData() {
return fetch('https://mywebsite.com/myotherdata')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
data: responseJson.data
});
})
.catch((error) => {
console.error(error);
});
}
componentDidMount() {
this.getData();
}
Then to get the values from the JSON response I am doing this:
this.state.data.name
I am having another issue, but I will create another question.
I've just started working with React Native a few days ago and I find myself a bit stuck. I want to display the values one by one from an api with the click of a button. However, how can I do this without fetching the data every single time, but rather every 10 clicks or so? The code I have right now doesn't work the way I want it to and I do understand why - the countData() function is always called anew, therefore the variable i is always stuck at zero and never advances forward. Ideally, I'd like to loop through the first set of values, display them one by one as the button is clicked and then fetch new data (from the same api) after it runs out of values.
export default class ComponentOne extends Component {
constructor(props) {
super(props);
this.state = {
questions: '',
questions2: '',
}
}
fetchData() {
if (this.state.questions == '') {
fetch('my url')
.then((response) => response.json())
.then((responseData) => {
this.setState({
questions: responseData,
});
this.countData();
})
.done();
}
else this.countData();
}
countData() {
for (let i=0; i < this.state.questions.length; i++) {
this.setState({
questions2: this.state.questions[i],
});
}
}
render() {
return (
<View style={styles.container}>
<View style={styles.textStyle}>
<Text style={styles.instructions}>
Welcome! Click the button to generate a question.
</Text>
<TouchableHighlight
onPress={() => this.fetchData()}
style={styles.bigButton}
underlayColor="lightskyblue">
<Text style={styles.bigButtonText}>Hit me</Text>
</TouchableHighlight>
<Text style={styles.question}>{this.state.questions2}</Text>
</View>
</View>
);
}
}
I hope the problem is clear, thanks in advance!
First things first: you should consider not giving you apis url like that.
I didn't test the code in an app but it should work
export default class ComponentOne extends Component {
constructor(props) {
super(props);
this.state = {
questions: [],
question: "",
count: 0,
}
}
componentWillMount() {
this.fetchData();
}
fetchData() {
fetch('YOUR_URL')
.then((response) => response.JSON())
.then((responseJSON) => {
this.setState({questions: responseJSON, count: 0})
})
}
newQuestion() {
if (this.state.questions[count] != null) {
this.setState({
question: this.state.questions[this.state.count],
count: this.state.count + 1,
})
}
else { //make the fetch call once all of your questions has been displayed
this.fetchData();
}
}
render() {
return (
<View style={styles.container}>
<TouchableHighlight onPress={() => this.newQuestion()}>
<Text>Hit me</Text>
</TouchableHighlight>
<Text>{this.state.question}</Text>
</View>
</View>
);
}
}