TouchableOpacity deletes without touching - firebase

So I want to use TouchableOpacity in order to press on the component and delete data from the Firebase, but instead it's deletes everything in my firebase if I do
OnPress= {this.DeleteAds(item.key)}
I tried follow instructions in here TouchableOpacity execute without touching but now the button doesn't do anything.
Here is the code :
export default class Ads extends Component {
constructor(props){
super(props);
this.state={
adlist:[],
} }
DeleteAds = (key)=>{
firebase.database().ref('/ads/'+key).remove();
navigation.navigate("Home")
console.log(key)
};
componentDidMount(){
firebase.database().ref('/ads').on('value', (snapshot) =>{
var list = []
snapshot.forEach((child)=>{
list.push({
key:child.key,
title:child.val().title,
details: child.val().details
})
})
this.setState({adlist:list})
})
}
render(){
return(
<View style={styles.container}>
<View style={styles.container_3}>
<Text> Ads</Text>
</View>
<FlatList
data={this.state.adlist}
keyExtractor={(item)=>item.key}
renderItem={({item})=>{
return(
<TouchableOpacity OnPress ={()=>this.DeleteAds(item.key)}>
<View style={styles.container_2}>
<Text style={styles.text_style1}>{item.title}</Text>
<Text>{item.details}</Text>
</View>
</TouchableOpacity>
)}}/>
</View>
)}
}
I will be grateful if you help to fix the issue.

Related

How to style diffently item in a flatlist?

Hi everyone i have a problem styling every item present in a flatlist. i find on stackoverflow that you have to use index in the render item but in the render item i have a component that contains all of my items .
What i wanted to reach is this result :
here is my code in the home component:
import React, {useEffect, useState} from 'react';
import {
FlatList,
Pressable,
ScrollView,
StyleSheet,
Text,
View,
} from 'react-native';
import {Audio, Book} from '../types';
import customData from '../books.json';
import BookBox from '../components/BookBox';
import Menu from 'react-native-vector-icons/Entypo';
import Glass from 'react-native-vector-icons/Entypo';
export default function HomeScreen() {
const [books, setBooks] = useState<Book[]>([]);
const [audio, setAudio] = useState<Audio[]>([]);
const [selected, setSelected] = useState(false);
const [selectedAudio, setSelectedAudio] = useState(false);
useEffect(() => {
setBooks(customData);
}, []);
const renderBooks = ({item}: {item: Book}) => <BookBox book={item} />;
return (
<ScrollView nestedScrollEnabled={true} style={styles.scrollContainer}>
<View style={styles.searchContainer}>
<Menu name={'menu'} size={30} color={'black'} />
<Text style={styles.textSearch}>All Books</Text>
<Glass name={'magnifying-glass'} size={30} color={'black'} />
</View>
<View style={styles.AudioOrEbookContainer}>
<Pressable
onPress={() => setSelected(!selected)}
style={{backgroundColor: selected ? 'white' : 'transparent'}}>
<View style={styles.btn}>
<Text>Ebook</Text>
</View>
</Pressable>
<Pressable
style={{backgroundColor: selectedAudio ? 'white' : 'transparent'}}>
<View style={styles.btn}>
<Text>Audiobook</Text>
</View>
</Pressable>
</View>
<View style={styles.container}>
<FlatList
data={books}
keyExtractor={item => item.id?.toString()}
renderItem={renderBooks}
numColumns={2}
/>
</View>
</ScrollView>
);
}
here is my code in BookBox component:
import {Text, Image, StyleSheet, View, TouchableHighlight} from 'react-native';
import React from 'react';
import {Book} from '../types';
import {useNavigation} from '#react-navigation/native';
interface Props {
book: Book;
}
export default function BookBox({book}: Props) {
const {
author,
country,
imageLink,
language,
link,
pages,
title,
year,
overview,
vote,
} = book;
const navigation = useNavigation();
return (
<View style={styles.container}>
{imageLink && (
<TouchableHighlight
onPress={() =>
navigation.navigate('SingleBook', {
title,
year,
pages,
link,
language,
imageLink,
country,
author,
overview,
vote,
})
}>
<Image
style={styles.image}
source={{
uri: `${imageLink}`,
}}
/>
</TouchableHighlight>
)}
{!imageLink && <Text>immagine mancante</Text>}
<View style={styles.wrap}>
<Text style={styles.title}>{title}</Text>
<Text style={styles.title}>{author}</Text>
</View>
</View>
);
}
i'm trying to render items with unique style like in the image above.. can you help me? thank you in avance
So, numColumns of FlatList cannot help you to achieve the behavior you want. This is because masonry are not supported by this property, in other words, numColumns sets the same height for every item at the same line. As a resort to implementing this behavior you can check this lib: https://github.com/hyochan/react-native-masonry-list

Error: [auth/unknown] Cannot create PhoneAuthCredential without either verificationProof, sessionInfo, temporary proof, or enrollment ID

I am trying to make a Login page with Phone Authentication to use React-Native-Firebase sdk and I receive OTP through sms and when I confirm the received OTP ,I got a error that: [Error: [auth/unknown] Cannot create PhoneAuthCredential without either verificationProof, sessionInfo, temporary proof, or enrollment ID.]
I am using-
React:18.0.0
React-Native: 0.69.1
React-Native-Firebase:^15.1.1
My code is-
import React, {useState} from 'react';
import {
View,
Text,
StyleSheet,
Image,
TextInput,
TouchableOpacity,
Alert,
} from 'react-native';
import PhoneInput from 'react-native-phone-number-input';
import auth from '#react-native-firebase/auth';
const Login = () => {
const [PhoneNumber, setPhoneNumber] = useState('');
const [otpInput, setOtpInput] = useState('');
const [confirmData, setConfirmData] = useState('');
const sendOtp = async () => {
try {
const responce = await auth().signInWithPhoneNumber(PhoneNumber);
setConfirmData(responce);
console.log(responce);
Alert.alert('Otp is sent please varify it');
} catch (error) {
console.log(error);
}
}
const submitOtp = async () => {
try {
const responce = await confirmData.confirm(otpInput);
console.log(responce);
Alert.alert('Your Number is verified');
} catch (error) {
console.log(error);
}
}
return (
<View>
<View style={styles.con}>
<Text style={styles.container}>Login Screen</Text>
<Image source={require('../assets/logo.png')} style={styles.image} />
</View>
<View style={styles.inputContainer}>
<Text style={styles.labels}>Phone Number:</Text>
<PhoneInput
style={styles.inputStyle}
defaultValue={PhoneNumber}
defaultCode="DM"
layout="first"
keyboardType="number-pad"
onChangeFormattedText={text => setPhoneNumber(text)}
onChangeText={(value) => setPhoneNumber(value)}
/>
</View>
<View>
<TouchableOpacity
style={styles.buttonStyle}>
<Text style={styles.buttonText}>Verify</Text>
</TouchableOpacity>
</View>
<View style={styles.otpContainer}>
<TextInput
style={styles.otpStyle}
placeholder="Enter OTP"
autoCapitalize="none"
secureTextEntry={true}
onChangeText={(value) => setOtpInput(value)}/>
</View>
<View>
<TouchableOpacity style={styles.continueStyle}>
<Text
style={styles.buttonText}
onPress={() => submitOtp()}>
Continue
</Text>
</TouchableOpacity>
</View>
</View>
);
};
export default Login;

Adding doc to firebase using react native and encountering many errors with promises/async storage

So im trying to make a todo list app and making the fucntion to add a doc to firebase. However, when i do that expo says the async storage has been deprecated and that there is a unhandled promise rejection
my code in my app:
import React, { useEffect } from 'react';
import {useState} from "react"
import { SafeAreaView, Text, View, Button, TouchableOpacity, Modal, StyleSheet,Pressable, TextInput } from 'react-native';
import { collection, doc, setDoc, query, getDocs, onSnapshot, addDoc, orderBy, limit, Timestamp, where} from "firebase/firestore";
import {db} from "../firebase"
import { signPlsOut } from '../firebase';
import { auth } from '../firebase';
import AsyncStorage from '#react-native-async-storage/async-storage';
export const Dashboard = () => {
const {uid, photoURL, displayName} = auth.currentUser;
const projectsref = collection(db, "projects");
const [modalVisible, setModalVisible] = useState(false);
const [projects, setProjects] = useState([])
const [desc, setDesc] = useState("");
const [title, setTitle] = useState("");
async function handleAddTask () {
try {
await addDoc(projectsref, {
title: title,
desc: desc,
createdAt: Timestamp.fromDate(new Date()),
uid: uid,
})
setTitle("")
setDesc("")
setModalVisible(false)
}
catch(error) {
console.log('There has been a problem with your fetch operation: ' + error.message);
// ADD THIS THROW error
throw error;
}
}
return (
<SafeAreaView>
<View style={{
margin: 20
}}>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
Alert.alert("Modal has been closed.");
setModalVisible(!modalVisible);
}}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Text style={styles.modalText}>Add task:</Text>
<View style={{marginBottom: 20}}>
<TextInput placeholder='title' value={title} onChange={(e) => setTitle(e.target.value)}></TextInput>
<TextInput placeholder='description' value={desc} onChange={(e) => setDesc(e.target.value)}></TextInput>
</View>
<Button title='submit todo' onPress={handleAddTask}></Button>
<Pressable
style={[styles.button, styles.buttonClose]}
onPress={() => setModalVisible(!modalVisible)}
>
<Text style={styles.textStyle}>Cancel</Text>
</Pressable>
</View>
</View>
</Modal>
<Text style={{fontSize: 20, fontWeight: "500"}}>Welcome,</Text>
<Text style={{fontSize: 27, fontWeight: "700"}}>{auth.currentUser.email}</Text>
<View style={{marginTop: 30}}>
<Text style={{fontSize: 40, fontWeight: "700", color: "#0404"}}>Create Task</Text>
<TouchableOpacity>
<View style={{
backgroundColor: "orange",
borderRadius: "20px"
}}>
<Pressable
style={[styles.button, styles.buttonOpen]}
onPress={() => setModalVisible(true)}
>
<Text style={styles.textStyle}>Add task</Text>
</Pressable>
</View>
</TouchableOpacity>
</View>
<Button title="signout" onPress={signPlsOut}></Button>
</View>
</SafeAreaView>
);
};
error:
async sotrage has been extracted and will be removed in a future release, in addition to the unhandled promise rejection error
Are you able to actually add the doc to firebase? Some more context would be helpful in what you're trying to do. Is you code above completely unsucessful and you are getting errors? Or are you simply trying to clear errors.
If you are just trying to get rid of the unhandled promise rejection. I ran into a similar error and I found where in the Firebase app node_module where the call out was being for async storage. For me to get rid of a similar error i did two steps:
First, i installed the new react native async storage module:
npm install #react-native-async-storage/async-storage
Next, i had to update firebase app module, in the following file, to point to the appropriate API within my expo app to point to this new react native async storage module.
./node_modules/#firebase/app/dist/index.rn.cjs.js
I had to adjust this bit of code in this file:
var AsyncStorage = require('#react-native-async-storage/async-storage').AsyncStorage;
firebase.INTERNAL.extendNamespace({
INTERNAL: {
reactNative: {
AsyncStorage: AsyncStorage
}
}
});
The above code previously called to "react" i believe, i just needed to update it to specifically call to "#react-native-async-storage/async-storage". And this solved my problem.

How to Update document data in firebase with react-native Possible Unhandled Promise Rejection (id: 37)

The error I'm facing is "Possible Unhandled Promise Rejection (id: 37)"
class AgentDashBoard extends React.Component{
state={
Couriers: [],
ids:[],
Courier_Location: "",
Courier_Status: ""
}
constructor(props){
super(props);
this.subscriber=
firestore()
.collection("Couriers")
.onSnapshot(docs =>{
let Couriers=[]
let ids=[]
docs.forEach(doc=>{
Couriers.push(doc.data())
ids.push(doc.id)
})
this.setState({Couriers})
this.setState({ids})
})
}
updateshipment= (trackid)=> {
firestore()
.collection("Couriers")
.doc(this.state.ids[trackid])
.update({CurrentLocation: this.state.Courier_Location, CurrentStatus: this.state.Courier_Status})
}
render(){
return(
<ScrollView style={{...}}>
<Text style={{...}}> Couriers for Delivery </Text>
{this.state.Couriers.map((Courier, index) =>
<View
key={index}
style={{...}}
>
<View style={{...}}>
<TextInput
style={{...}}
onChangeText={text=>this.setState({ Courier_Location: text})}
placeholder="Current Location">
{Courier.CurrentLocation}
</TextInput>
<TextInput
style={{...}}
onChangeText={text=>this.setState({Courier_Status: text})}
placeholder="Current Status">
{Courier.CurrentStatus}
</TextInput>
<Icon
name="check"
size={25}
style={{...}}
onPress= {(index)=>
this.updateshipment(index)
}
/>
</View>
</View> )}
</ScrollView>
);
}
}
export default AgentDashBoard
Is there a way to display the CurrentLocation and CurrentStatus in 2 textinputs as I have tried to do and then edit that location and status just for one instance within the same onPress function.
The ids[index] returns the document id correctly but I'm unable to use that what can I do?

How to pull key from firebase realtime database and pass to edit screen?

I am pretty new to react native/firebase, and am trying to figure out how to grab the unique key from an entry in the database (they are randomly generated when using Push), so I can update the database entry on my edit screen. Any help or direction on how I could accomplish this is very much appreciated.
Here is my main feed screen where all items from the database are grabbed and displayed:
let ref = db.ref('dogs');
export default class Main extends React.Component {
_isMounted = false;
constructor() {
super();
this.state = {
currentUser: null,
errorMessage: null,
items: [],
key: '',
};
}
componentDidMount() {
this._isMounted = true;
const {currentUser} = firebaseAuth;
this.setState({currentUser});
ref.on('value', snapshot => {
if (this._isMounted) {
let data = snapshot.val();
let items = Object.values(data);
this.setState({items});
}
});
}
componentWillUnmount() {
this._isMounted = false;
}
render() {
const {currentUser} = this.state;
return (
<View style={styles.container}>
<View>
<View style={styles.container}>
{this.state.items.length > 0 ? (
<ItemComponent
style={styles.listDog}
items={this.state.items}
navigation={this.props.navigation}
/>
) : (
<Text>No dogs</Text>
)}
</View>
<View style={styles.bottomContainer}>
<TouchableOpacity
style={styles.addBtn}
onPress={() => this.props.navigation.navigate('dogCreation')}>
<View>
<FontAwesomeIcon style={styles.penIcon} icon={faBone} />
</View>
</TouchableOpacity>
</View>
</View>
</View>
);
}
}
here is my item component:
export default class ItemComponent extends Component {
static propTypes = {
items: PropTypes.array.isRequired,
};
render() {
return (
<View style={styles.itemsList}>
{this.props.items.map((item, dog) => {
return (
<TouchableOpacity
key={dog}
onPress={() =>
this.props.navigation.navigate('Profile', {
name: item.name,
image_uri: item.image_uri,
parent: item.parent,
parentEmail: item.parentEmail,
parentTwo: item.parentTwo,
parentTwoEmail: item.parentTwoEmail,
})
}>
<View style={styles.dogCard}>
<Image source={{uri: item.image_uri}} style={styles.dogImage} />
<Text style={styles.itemtext}>{item.name} </Text>
<FontAwesomeIcon style={styles.chevron} icon={faChevronRight} />
</View>
</TouchableOpacity>
);
})}
</View>
);
}
}
here is my profile page:
export default class Profile extends React.Component {
render() {
const {navigation} = this.props;
const dogName = navigation.getParam('name', '');
const image_uri = navigation.getParam('image_uri', '');
const parent = navigation.getParam('parent', '');
const parentEmail = navigation.getParam('parentEmail', '');
const parentTwo = navigation.getParam('parentTwo', '');
const parentTwoEmail = navigation.getParam('parentTwoEmail', '');
return (
<View style={styles.container}>
<Image style={styles.dogImage} source={{uri: image_uri}} />
<View style={styles.contentBlock}>
<Text style={styles.header}>Name</Text>
<Text style={styles.textStyle}>{dogName}</Text>
</View>
<View style={styles.contentBlock}>
<Text style={styles.header}>Pet Parent 1 Info</Text>
<Text style={styles.subHeader}>Name</Text>
<Text style={styles.textStyle}>{parent}</Text>
<Text style={styles.subHeader}>Name</Text>
<Text style={styles.textStyle}>{parentEmail}</Text>
</View>
<View style={styles.contentBlock}>
<Text style={styles.header}>Pet Parent 2 Info</Text>
<Text style={styles.subHeader}>Name</Text>
<Text style={styles.textStyle}>{parentTwo}</Text>
<Text style={styles.subHeader}>Name</Text>
<Text style={styles.textStyle}>{parentTwoEmail}</Text>
</View>
<TouchableOpacity
style={styles.addBtn}
onPress={() =>
this.props.navigation.navigate('editProfile', {
name: dogName,
image_uri: image_uri,
parent: parent,
parentEmail: parentEmail,
parentTwo: parentTwo,
parentTwoEmail: parentTwoEmail,
})
}>
<Text>EDIT</Text>
</TouchableOpacity>
</View>
);
}
}
and here is my edit profile page update function:
let ref = db.ref('dogs');
let addItem = (
dog,
parent,
parentEmail,
parentTwo,
parentTwoEmail,
image_uri,
) => {
db.ref('/dogs/')
.update({
name: dog,
parent: parent,
parentEmail: parentEmail,
parentTwo: parentTwo,
parentTwoEmail: parentTwoEmail,
image_uri: image_uri,
});
};
just use on return snapshot return snapshot.key.
ref.on('value', snapshot => {
if (this._isMounted) {
let id = snapshot.key;
let data = snapshot.val();
let items = Object.values(data);
this.setState({items});
}
});
you can see more details here: https://firebase.google.com/docs/reference/js/firebase.database.DataSnapshot#key
**some important points, if you are using the firebase library directly in react native, I advise you to use the version created specifically for React Native, which corrects several problems of timers within the OS.
you can see here: https://rnfirebase.io/
**other importante detail, your firebase return function is a listener, and using this._isMounted is anti patern. you can use subscriber to stop the listener.
so...
let subscriber;
...
componentDidMount() {
const {currentUser} = firebaseAuth;
this.setState({currentUser});
subscriber = ref.on('value', snapshot => {
let data = snapshot.val();
let items = Object.values(data);
this.setState({items});
});
}
componentWillUnmount() {
// Stop listening for updates when no longer required
this.subscriber();
}

Resources