Adding Realtime firebase data with useState to a flatlist - reactjs

I want to take this data and display it in a flatlist. I tried the way described below, but it wont show me anything in the flatlist. How would i be able to solve this problem?
Code for fetching data
useEffect(() => {
refComment.once('value').then(snapshot=>{
var li=[]
snapshot.forEach((child) => {
li.push({
// avatarIcon : child.val().avatarIcon,
// commentText : child.val().commentText,
// name : child.val().name,
// time : child.val().time,
// id : child.key
key:child.key,
comment:child.val()
}
)
}
)
setcommentData(li)
console.log(li);
})
} , []);
code for my flatlist
<Card>
<View style={styles.answerDetailsView}>
<View style={styles.allContentView}>
<Text style={styles.allContentText}>Tüm yorumlar</Text>
</View>
<Divider/>
<FlatList
data={commentData}
keyExtractor={(item)=>item.key}
renderItem={({item,index})=>{
return(
<View
index={index}
style={styles.contentView}>
<View style={styles.commentatorDetailView}>
<View style={styles.commentatorAvatarView}>
<Avatar.Icon
size={30}
icon={item.avatarIcon}
/>
</View>
<View style={styles.commentatorNameAndTimeView}>
<Text>{item.name}</Text>
<Text>{item.time}</Text>
</View>
<View style={styles.commentatorLikeView}>
<TouchableOpacity>
<Icon
name='thumbs-up'
/>
</TouchableOpacity>
</View>
</View>
<View style={styles.contentTextView}>
<Text style={styles.contentText}>
{item.commentText}
</Text>
</View>
</View>
)
}}
/>
</View>
</Card>
And RealTime firebase screen
enter image description here
my mobile screenshot
enter image description here

Try to refactor logic to fetch comments as below:
function getComments() {
const commentsRef = firebase.database().ref("comments");
commentsRef.on("value", (snapshot) => {
if (snapshot.val()) {
const data = snapshot.val();
const comments = Object.values(data) || [];
setcommentData(comments);
}
});
}
useEffect(() => {
getComments();
}, []);

Related

#gorrhom React Native Bottom Sheet - Calling from another component

Im trying to implement this relatively popular bottom sheet in React Native by #gorhom.
My aim is to open the bottom sheet from another component. I've tried to follow this answer - here . However, i do not understand what goes in the touchable opacity onPress in my component where it is being called from.
Code below
BottomSheetModalComponent
export default function BottomSheetModalComponent({ref}) {
// ref
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
// variables
const snapPoints = useMemo(() => ['25%', '50%'], []);
// callbacks
const handlePresentModalPress = useCallback(() => {
ref.current?.present();
}, []);
const handleSheetChanges = useCallback((index: number) => {
console.log('handleSheetChanges', index);
}, []);
// renders
return (
<BottomSheetModalProvider>
<View>
<BottomSheetModal
ref={ref}
snapPoints={snapPoints}
onChange={handleSheetChanges}
>
<View>
<Text>Awesome 🎉</Text>
</View>
</BottomSheetModal>
</View>
</BottomSheetModalProvider>
);
};
Location Component
export default function LocationBar() {
// Create Ref
const userBottomSheetRef = useRef<BottomSheetModal>(null);
// Pass ref into the bottom sheet component
<LocationBottomSheet ref={userBottomSheetRef} snapPoints={["30%"]}/>
return (
<>
<View style={{ flexDirection: "row" }}>
<View style={styles.locationBar}>
<Octicons style={styles.locationIcon} name="location" size={18} />
<TouchableOpacity onPress={() => {
//WHAT GOES HERE?
}}>
<Text style={{fontSize: 17, fontWeight: '600'}}>{userLocation}</Text>
</TouchableOpacity>
<Ionicons style={styles.chevronIcon} name="chevron-down" size={12} />
</View>
</View>
</>
);
}
Thanks in advance

question how do you display content that is stored in the firebase in react native

useEffect(() => {
todoRef.orderBy('createAt', 'desc').onSnapshot((querySnapshot) => {
const todos = [];
querySnapshot.forEach((doc) => {
const { heading } = doc.data();
todos.push({ id: doc.id, heading });
});
setTodos(todos);
});
}, []);
//dealate a todo from firebase database
const dealateTodo = (todos) => {
todoRef
.doc(todos, id)
.delete()
.then(() => {
// Show a successful alert after deleting
alert('Deleted Successfully');
})
.catch((error) => {
alert(error);
});
};
// add a todo
const addTodo = (todo) => {
// checking is there a todo in here
if (addData && addData.length > 0) {
// get the timestamp
const timestamp = firebase.firestore.FieldValue.serverTimestamp();
const data = {
heading: addData,
createdAt: timestamp,
};
todoRef
.add(data)
.then(() => {
setAddData('');
Keyboard.dismiss();
})
.catch((error) => {
alert(error);
});
}
};
return (
<View style={styles.flex_1}>
<ScrollView
data={todos}
renderItem={({ item }) => (
<View>
<Pressable
style={styles.container}
onPress={() => navigation.navigate('Detail', { item })}
>
<FontAwesome
name='trash'
color='red'
onPress={() => dealateTodo(item)}
style={styles.todoIcon}
/>
<View style={styles.innerContainer}>
<Text style={styles.itemHeading}>
[item.Heading[0].toUpperCase() + item.heading.slice(1)]
</Text>
</View>
</Pressable>
</View>
)}
/>
<View style={styles.formContainer}>
<TextInput
style={styles.txt_input}
placeholder='Enter Task Title'
placeholderTextColor='#aaaaaa'
onChangeText={(heading) => setAddData(heading)}
value={addData}
underlineColorAndroid='transparent'
autoCapitalize='none'
/>
<TouchableOpacity style={styles.button} onPress={addTodo}>
<Text style={styles.buttonText}>+</Text>
</TouchableOpacity>
</View>
</View>
);
I wrote This code to display the Data stored in the firebase but it doesn't display can anyone help?
please! (comment if you need the full file)
You are using a ScrollView and try to use it like a FlatList. The ScrollView does not define a renderItem or data prop. Use a FlatList or use the map function to map over todos.
Furthermore, you need to add {} around code that you are calling for objects within a component not [].
Here is a version using FlatList.
<FlatList
data={todos}
renderItem={({ item }) => (
<View>
<Pressable
style={styles.container}
>
<View style={styles.innerContainer}>
<Text style={styles.itemHeading}>
{item.Heading[0].toUpperCase() + item.heading.slice(1)}
</Text>
</View>
</Pressable>
</View>
)}
/>
Here is a version using ScrollView and map.
<ScrollView>
{
todos.map(item => <View>
<Pressable
style={styles.container}
>
<View style={styles.innerContainer}>
<Text style={styles.itemHeading}>
{item.Heading[0].toUpperCase() + item.heading.slice(1)}
</Text>
</View>
</Pressable>
</View>)
}
</ScrollView>

null is not an object (evaluating 'teachers.length')

const [teachers, setTeachers] = useState([]);
const teachersList = async () => {
setLoading(true);
const storedValue = await AsyncStorage.getItem('#teachers_list');
if (!storedValue) {
setTeachers([]);
}
const list = JSON.parse(storedValue);
setTeachers(list);
setLoading(false);
}
useEffect(() => {
teachersList();
}, [isFocused])
return (
<SafeAreaView>
<ScrollView style={styles.mainContainer}>
{teachers.length == 0 ? (
<View style={styles.noData}>
<Text>Teacher List Empty</Text>
</View>
) : (
<>
{
teachers.map((teacher) => (
<View key={teacher.id} style={styles.productContainer} >
<View style={styles.productDetails}>
<Text> Name : {teacher.name}</Text>
<Text> Subject : {teacher.subject}</Text>
<Text> Email : {teacher.email}</Text>
</View>
<View style={styles.productButtonContainer}>
<TouchableOpacity style={styles.productActionEditButton} onPress={() => navigation.navigate("Edit", { teacher })}>
<Text> Edit </Text>
</TouchableOpacity>
<TouchableOpacity style={styles.productActionDelButton} onPress={() => deleteTeacher(teacher.id)}>
<Text> Delete </Text>
</TouchableOpacity>
</View>
</View>
))
}
</>
)}
</ScrollView>
</SafeAreaView>
)
The following code giving me an error. It was working when I was creating this application but now it's not working and showing me this error. I tried teachers && (code) but it is not working
null is not an object (evaluating 'teachers.length')
Edit: I just had to re-think the requirements of what you are doing
Instead of this:
teachers.length == 0 ? (
<View style={styles.noData}>
<Text>Teacher List Empty</Text>
</View>
)
try using this:
!teachers || teachers.length == 0 ? (
<View style={styles.noData}>
<Text>Teacher List Empty</Text>
</View>
)

Navigation from menu item

I'm trying to get a menu item to navigate to another page but for some reason it wont let me do it. I'm a little confused as to how you go about it and any help is welcome!
Import here:
import { NavigationScreenProp } from "react-navigation";
Here is more code:
interface NotificationDropdownProps {
navigation: NavigationScreenProp<any, any>;
}
Here is where function is called:
function renderNotification(notification: INotification) {
return (
<MenuOption
onSelect={() => {
if (notification.type == INotificationType.SYSTEM) {
this.testFunction();
}
}}
>
<View style={[styles.notificationContainer]}>
<View style={styles.iconArea}>
<View style={[styles.iconCircle]}>
<Icon
name={this.getIconType(notification.type)}
color={this.notificationColor(notification.type)}
size={26}
/>
</View>
</View>
<View>
<Text>{notification.text}</Text>
<Text>
{this.getDate(new Date(notification.dateCreated))}
</Text>
</View>
</View>
</MenuOption>
);
}
Test Function:
testFunction(){
this.props.navigation.navigate('NextPage')
};
Error:
undefined is not an object(evaluating'_this2.props.naviagtion.navigate)
Where the function is called:
<View>
<Text>
Notifications
</Text>
{this.props.notifications.length > 0 ? (
<FlatList
contentContainerStyle={{ borderRadius: 10 }}
data={this.props.notifications.slice(0, 5)}
renderItem={({ item }) => this.renderNotification(item)}
keyExtractor={this.keyExtractor}
/>
) : (
<Text>No Notifications!</Text>
)}
</View>;
try with an arrow function to avoid using the context of the function.
testFunction = () => {
this.props.navigation.navigate('NextPage')
};

How to get object ID onPress and pass that value on to a new screen in React Native?

I've build an React Native app which shows a list of different objects on the ListScreen. I now want to with onPress show one object values on the ViewScreen
I've build my app using React-Redux and React-navigation now I'm not sure if I should store the data of the object in the store, but I'm not sure if that's the right way to use the Redux store (because I currently use it for the cart items) or If there is another way to pass on these value's on to the ViewScreen.
This is a simplification of my app:
I've made a static Data.js file to test app
Data.JS
`id: 0,
name: 'John Doe',
age: '15',
gender: 'male',
`
Then I import the data into the ListScreen
List.js
`import { object} from './Data';
state = {
object,
};
renderRow = (rowData) => {
return (
<View>
<TouchableOpacity onPress={() => this.props.id.navigation.navigate('ViewScreen')}>
<View>
<Text>
{rowData.item.name}
</Text>
</View>
</TouchableOpacity>
</View>
)
}
render() {
return (
<View>
<FlatList
renderItem={this.renderRow}
keyExtractor={(item, index) => index.toString()}
/>
</View>
)
}
`
ViewScreen
` state = {
object,
};
renderRow = (rowData) => {
return (
<View>
<TouchableOpacity onPress={() => this.props.id.navigation.navigate('ViewScreen')}>
<View>
<Text>
{rowData.item.name}
{rowData.item.age}
{rowData.item.gender}
</Text>
</View>
</TouchableOpacity>
</View>
)
}
render() {
return (
<View>
<FlatList
renderItem={this.renderRow}
keyExtractor={(item, index) => index.toString()}
/>
</View>
)
}
`
How do I pick it up from here? So that the value's get shown in the ViewScreen
you are almost there just add this second argument to your on press method and it's done.
You will get this data in data prop of next screen.
renderRow = (rowData) => {
return (
<View>
<TouchableOpacity onPress={() =>
this.props.id.navigation.navigate('ViewScreen',{data : rowData})}>
<View>
<Text>
{rowData.item.name}
{rowData.item.age}
{rowData.item.gender}
</Text>
</View>
</TouchableOpacity>
</View>
)
}

Resources