Delete document by getting document name in Cloud Firestore - javascript

Been working on finding a way to delete the clicked on document using React Native and Cloud Firestore. I can't figure out a way to get the document id and then use it in my code to replace the value of deleteItemId. Any ideas?
My collection with a document showing:
My code:
componentDidMount(){
this.getItems();
const { currentUser } = firebase.auth();
this.setState({ currentUser });
}
getItems = async () => {
this.setState({ refreshing: true });
this.unsubscribe = await this.ref.onSnapshot((querySnapshot) => {
const todos = [];
querySnapshot.forEach((doc) => {
todos.push({
tips: doc.data().tips,
date: doc.data().date,
user: doc.data().user,
like: doc.data().like
})
})
this.setState({
refreshing: false,
getData: todos
})
})
}
deletePost = () => {
const deleteItemId = "SELECTED DOCUEMNT ID HERE";
firestore.collection("tips").doc(deleteItemId).delete().then(function() {
alert("deleted")
}).catch(function(error) {
alert("Error removing document: ", error);
});
}
renderItem = ({ item, index }) => {
let date = item.date;
return (
<View style={styles.tips}>
<View style={styles.wrapper}>
<View style={styles.profilePicture}>
<View></View>
</View>
<View style={styles.right}>
<Text style={styles.username}>#{item.user}</Text>
<Text style={styles.date}>{ moment(item.date).fromNow() }</Text>
</View>
</View>
<Text style={styles.text}>{item.tips}</Text>
<View style={styles.bar}>
<Text><Icon onPress={() => this.like()} style={styles.heart} type="Octicons" name="heart" /> {item.like}</Text>
<Text onPress={() => {
this.setModalVisible(true);
}}><Icon style={styles.comment} type="FontAwesome" name="comment-o" /> {item.replies}</Text>
<Text onPress={() => this.deletePost()}><Icon style={styles.settings} type="Octicons" name="kebab-vertical" /></Text>
</View>
</View>
)
}

Every time you push a TODO to todos, make sure to also include the document ID:
todos.push({
id: doc.id,
tips: doc.data().tips,
date: doc.data().date,
user: doc.data().user,
like: doc.data().like
})
Then when you render a TODO, you include the ID in the rendering output of the eleent:
<Text onPress={() => this.deletePost(styles.id)}>

Related

Passing Params to Another Page Using React Native

how can I pass my type2 params on DoctorCategory to another page? I tried like these below, but it gets an error said can't find variable: type2
this type2 is the value from firebase
const Home = ({ navigation }) => {
const [categoryDoctor, setCategoryDoctor] = useState([])
useEffect(() => {
Fire.database()
.ref('category_doctor/')
.once('value')
.then(res => {
console.log('data category: ', res.val())
if (res.val()) {
setCategoryDoctor(res.val())
}
})
.catch(err => {
showError(err.message)
})
}, [])
useEffect(() => {
getData('user').then(res => {
console.log('data user:', res)
})
}, [])
return (
<View style={styles.content}>
<Text style={styles.welcome}>How can we help you?</Text>
<View style={styles.category}>
<DoctorCategory
type1='General'
type2={categoryDoctor.categoryA}
pic={ILLDocGen}
onPress={() => navigation.navigate('ChooseDoctor', type2)} //<== this one
/>
</View>
</View>
)}
And I call it on another page using.
const ChooseDoctor = ({navigation, route}) => {
const type = route.params
return (
<View style={styles.container}>
<Header1 type='light' title= {`Select a ${type.type2}`}/>
</View>
)}
you should use props in ChooseDoctor component! use this:
const ChooseDoctor = ({navigation, route, props}) => {
return (
<View style={styles.container}>
<Header1 type='light' title= {`Select a ${props.type2}`}/>
</View>
)}
The 2nd param is an object
onPress={() => navigation.navigate('ChooseDoctor',{
type2
)}
Reference https://reactnavigation.org/docs/params/#passing-params-to-nested-navigators

Contents of Firebase Firestore not rendering in my screen

I'm using react native to create a simple to-do app using Firebase. I used the firestore database. I am able to push the data into Firebase using user inputs. I also tried fetching the data in my screen but I cannot see the data.
dashboard.js ( I want the list of data to be shown here)
export default function Dash(){
const [task, setTask] = useState();
const [taskItems, setTaskItems] = useState([]);
const [loading, setLoading] = useState(true);
const todoCollection = db.collection('todos');
useEffect(() => {
return todoCollection.onSnapshot((querySnapshot) =>{
const list=[];
querySnapshot.forEach(doc => {
const {text, done} = doc.data();
list.push({
id: doc.id,
text,
done,
});
});
setTask(list);
if (loading) {
setLoading(false);
}
});
}, [])
async function addTask() {
await todoCollection.add({
text:task,
done: false,
}).then(()=> {
alert ("Task added Succesfully")
})
setTask('');
Keyboard.dismiss();
setTask(null);
}
const handleTask =()=>{
Keyboard.dismiss();
setTaskItems([...taskItems, task])
setTask(null);
}
const deleteTask = (index) => {
let itemsCopy = [...taskItems];
itemsCopy.splice(index,1);
setTaskItems(itemsCopy);
}
if (loading) {
return null;
}
return(
<>
<View style = {styles.tasksWrapper}>
<Text style={styles.sectionTitle} > ToDos List </Text>
<View style={{height:30}}></View>
<View style = {styles.items}>
{/* {
taskItems.map((item, index)=> {
return(
<Task text={item} del={deleteTask} i={index} />
)
})
} */}
<FlatList
style={{flex: 1}}
data={task}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <Todo {...item} />}
/>
</View>
</View>
<KeyboardAvoidingView behavior={Platform.OS ==="ios"? "padding": "height"}
style={styles.writeTaskWrapper}>
<TextInput style={styles.input} placeholder={'write a task'} value={task} onChangeText={text => setTask(text)}/>
<TouchableOpacity onPress={()=>addTask()}>
<View style={styles.addWrapper}>
<Text style={styles.addText}> + </Text>
</View>
</TouchableOpacity>
</KeyboardAvoidingView>
</>
)
}
Todo.js
import React from 'react';
import {db} from '../firebase/fire';
import { List } from 'react-native-paper';
function Todo({ id, text, done }) {
async function toggleComplete() {
await db
.collection('todos')
.doc(id)
.update({
done: !done,
});
}
return (
<List.Item
text={text}
onPress={() => toggleComplete()}
left={props => (
<List.Icon {...props} icon={done ? 'check' : 'cancel'} />
)}
/>
);
}
export default React.memo(Todo);
The app shows no error but the list is not rendering.

display firebase data on a flatlist

I'm trying to display a bunch of data i have on firebase in a flatlist, I don't really know where the problem is right now, i've tried physically filling the array out and that works but it doesn't when i get the data from firebase. I do see that im getting the data on the console log but it's not getting displayed.
function Squad() {
const gk = [];
db.collection('squad').orderBy('position').get().then(snapshot => {
snapshot.forEach(doc => {
const playerObject = doc.data();
gk.push({name: playerObject.name, number: playerObject.number});
console.log(gk);
});
});
const Item = ({ name, number }) => (
<View style={styles.item}>
<Text style={styles.itemText}>{number} - {name}</Text>
</View>
);
const renderItem = ({ item }) => (
<Item name={item.name} number={item.number} />
)
return(
<View>
<View style={styles.bar}>
<Text style={styles.barText}>goalkeeper</Text>
</View>
<FlatList
data={gk}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
</View>
)
}
You can get the info on mount in an async function, then store it in a stateful array using hooks.
function Squad() {
const [gk, setGk] = useState([]);
const getSquad = async () => {
const ref = db.collection('squad').orderBy('position');
const doc = await ref.get();
const playerObject = doc.data();
const newGk = [...gk, {name: playerObject.name, number: playerObject.number}];
setGk(newGk);
}
useEffect(() => {
getSquad();
}, [])
const Item = ({ name, number }) => (
<View style={styles.item}>
<Text style={styles.itemText}>{number} - {name}</Text>
</View>
);
const renderItem = ({ item }) => (
<Item name={item.name} number={item.number} />
)
return(
<View>
<View style={styles.bar}>
<Text style={styles.barText}>goalkeeper</Text>
</View>
<FlatList
data={gk}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
</View>
)
}
Start by creating a useEffect hook to act as a componentWillMount function to call the method when the compnent is ready. I have also included catch block in order to show any errors that might occur.
import React, { useState, useEffect } from "react";
const Squad = () => {
const [gk, setGK] = useState([]);
useEffect(() => {
getSquadData();
});
const getSquadData = () => {
db.collection("squad")
.orderBy("position")
.get()
.then((snapshot) => {
let myData = [];
snapshot.forEach((doc) => {
const playerObject = doc.data();
myData.push({
id: playerObject.id,
name: playerObject.name,
number: playerObject.number,
});
});
setGK(myData);
})
.catch((error) => {
console.log("Error getting data: ", error);
});
};
const Item = ({ name, number }) => (
<View style={styles.item}>
<Text style={styles.itemText}>
{number} - {name}
</Text>
</View>
);
const renderItem = ({ item }) => (
<Item name={item.name} number={item.number} />
);
return (
<View>
<View style={styles.bar}>
<Text style={styles.barText}>goalkeeper</Text>
</View>
<FlatList
data={gk}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
</View>
);
};
export default Squad;
So if you are seeing error logs in your console, check your collection in firestore, and also check the rules in your firestore.

Asyncstorage revives state for the wrong room

I am new to coding. Currently tryin to make a mobile app in react-native + firebase.
I am stuck at some really simple ( as i think ) stage, but spent a couple of days now but cannot find an answer.
In my app, user can create or enter room. Once created, room generates specific folder in firebase.
Creating and entering rooms work fine.
But whhen user enters a new room , he observes the state from the previous room even though it suppose to be blank as this is his first entry.
I dont understand how to solve this problem, absolutely crying now. A
Any help is appreciated.
This is a part of code where state is saved:
class ChatRoom extends React.Component {
constructor(zaza) {
super(zaza);
this.state = {
allTasksComplete: false,
task1: false,
task2: false,
task3: false,
task4: false,
task5: false,
task6: false,
task7: false,
finishedTasks: null,
zozo: false,
newRoomName: '',
creator: '',
};
}
generateTask = async (taskIndex, taskName,) => {
const creatorCheck = await AsyncStorage.getItem('nickname')
this.setState({creator: creatorCheck})
const nicknameSnap = await collectionRef.where('roomName', '==', this.state.newRoomName).get()
const nickCheck = nicknameSnap.docs[0].data()
if(nickCheck.creator === this.state.creator) {
firestore()
.collection('Rooms')
.doc(this.state.newRoomName)
.collection('Alpha')
.doc(taskIndex)
.set({
taskText: taskName,
})
.then(() => {
console.log('Task added')
})
}
else {
firestore()
.collection('Rooms')
.doc(this.state.newRoomName)
.collection('Beta')
.doc(taskIndex)
.set({
taskText: taskName,
})
.then(() => {
console.log('Task added')
})
} }
async componentDidMount() {
try {
const trytextx = await AsyncStorage.getItem('currentRoom')
const trial = JSON.parse(trytextx)
const maybe1 = await AsyncStorage.getItem('task1')
const string1 = JSON.parse(maybe1)
const maybe2 = await AsyncStorage.getItem('task2')
const string2 = JSON.parse(maybe2)
this.setState({newRoomName: trial})
if (string1 === false) {
this.setState({task1: false})
} else {
this.setState({ task1: string1 })
}
if (string2 === false) {
this.setState({task2: false})
} else {
this.setState({ task2: string2 })
}
} catch (e) {
console.log(e)
}
db.collection('Rooms')
.doc('RRN')
.collection('Alpha')
.get()
.then(snapshot => {
const tasks = []
snapshot.forEach(doc => {
const data = doc.data()
tasks.push(data)
})
this.setState({
finishedTasks: tasks
})
})
}
taskOne() {
if (this.state.task1) {
return (
<View>
<TaskOne />
<TouchableOpacity onPress={() => {
this.generateTask('Task1', 'First Task');
this.buttonTaskTwo()
}} raised='true' >
<View style={styles.buttonDone2}>
<Text style={styles.buttonText2}>
Выполнено
</Text>
</View>
</TouchableOpacity>
</View>
)
}
}
taskTwo() {
if (this.state.task2) {
return (
<View>
<TaskTwo />
<TouchableOpacity onPress={() => {
this.generateTask('Task2', 'Second Task');
this.buttonTaskThree()
}}>
<View style={styles.buttonDone2}>
<Text style={styles.buttonText2}>
Выполнено
</Text>
</View>
</TouchableOpacity>
</View>
)
}
}
CongratsMsg() {
if (this.state.allTasksComplete) {
return (
<View>
<CongratsMsg />
<TouchableOpacity onPress={this.lastButton}>
<View style={styles.buttonDone}>
<Text style={styles.buttonText2}>
Получить
</Text>
</View>
</TouchableOpacity>
</View>
)
}
}
lastMessage() {
if (this.state.zozo) {
return (
<View style={styles.MessageBG}>
<View >
{
this.state.finishedTasks.map(task => {
return (
<View>
<Text style={styles.MessageText}>*** {task.taskText} ***</Text>
</View>
)
})
}
</View>
</View>
)
}
}
lastButton = async () => {
this.setState({ zozo: true })
}
buttonTaskOne = async () => {
this.setState({ task1: true })
try {
await AsyncStorage.setItem('task1', JSON.stringify(true))
/* firestore()
.collection('Rooms')
.doc(this.state.newRoomName)
.set({
firstVisit: false
}, { merge: true }) */
} catch (e) {
console.log(e)
}
}
buttonTaskTwo = async () => {
this.setState({ task2: true })
try {
await AsyncStorage.setItem('task2', JSON.stringify(true))
} catch (e) {
console.log(e)
}
}
buttonCongrats = () => {
this.setState({ allTasksComplete: true })
}
render() {
return (
<ImageBackground source={bgImage} style={styles.backgroundContainer}>
<ScrollView style={styles.secondBg}>
<DefaultMsg />
<TouchableOpacity onPress={this.buttonTaskOne}>
<View style={styles.buttonDone}>
<Text style={styles.buttonText2}>
Начать!
</Text>
</View>
</TouchableOpacity>
<View>
{this.taskOne()}
</View>
<View>
{this.taskTwo()}
</View>
<View>
{this.CongratsMsg()}
</View>
<View>
{this.lastMessage()}
</View>
</ScrollView>
</ImageBackground>
)
}
}
I end up saving my state in firebase instead of asyncstorage.

React Native, button changing for all items in list

I created a flat list in which if user click buy button it should change but it's changing for every items. It should only change that item user buy. Can someone tell me what's wrong in my code, below is my code
FlatList
<FlatList
data={this.props.items}
key={(items) => items.id.toString()}
numColumns={2}
renderItem={({ item }) => (
<CardBuyItem>
<Image style={styles.image} source={item.image} />
<View style={styles.detailContainer}>
<Text style={styles.title}>{item.title}</Text>
<Text style={styles.subTitle} numberOfLines={1}>
{item.subTitle}
</Text>
<Text style={styles.price}>Rs {item.price}</Text>
</View>
{this.props.button && this.props.added.length > 0 ? (
<View style={styles.add}>
<Text style={styles.quantity}>{item.quantity}</Text>
<MaterialCommunityIcons
style={styles.iconUp}
size={20}
name="plus-circle-outline"
onPress={() => this.props.addQuantity(item.id)}
/>
<MaterialCommunityIcons
style={styles.iconDown}
size={20}
name="minus-circle-outline"
onPress={() => this.props.subtractQuantity(item.id)}
/>
</View>
) : (
<View style={styles.buy}>
<Text
style={styles.buyonce}
onPress={() => {
this.props.addToCart(item.id);
this.props.showCart();
this.props.showButton(item.id);
}}
>
Buy Once
</Text>
</View>
)}
</CardBuyItem>
)}
/>
const mapStateToProps = (state) => {
return {
items: state.clothes.jeans,
button: state.clothes.showButton,
added: state.clothes.addedItems,
};
};
const mapDispatchToProps = (dispatch) => {
return {
addToCart: (id) => dispatch(addToCart(id)),
addQuantity: (id) => dispatch(addQuantity(id)),
subtractQuantity: (id) => dispatch(subtractQuantity(id)),
showCart: () => dispatch(showCart()),
showButton: (id) => dispatch(showButton(id)),
};
};
that's my flat list where button should change for that particular item
reducer
if (action.type === SHOW_BUTTON) {
let addedItem = state.jeans.find((item) => item.id === action.id);
return {
...state,
addedItem: addedItem,
showButton: action.showButton,
};
}
const initialstate = { showButton: false}
that's my reducer
action
export const showButton = (id) => {
return {
type: SHOW_BUTTON,
showButton: true,
id,
};
};
and that's my action for reducer
Can someone please tell me what's wrong with it?
Try to add count to your item and in your reducer put
item.forEach(cp => {
if (cp.id === action.id) {
cp.count += 1;
}
});

Categories