React-Native: Display/Render multiple images with snapshot.val() - firebase

I am trying to load multiple images in my react-native-app feed page. I have stored it in my database and am able to retrieve the data using snapshot.val(), however, I don't understand how to actually display/render it on the feed screen.
When I do console.log("CONSOLE.LOG --> Snapshot is: ", snapshot.val()), this is what I get
CONSOLE.LOG --> Snapshot is: Object {
"4aae-47bb-e0f7-36e2-7e66": Object {
"author": "edm9AAbPpFUWrO9HDXfV442QzSE2",
"caption": "Test 1",
"photo": Object {
"2e30-b971-5c62-0b68-837f": Object {
"url": "https://firebasestorage.googleapis.com/v0/b/...someURL...",
},
"38de-15f2-bb7b-b58d-e863": Object {
"url": "https://firebasestorage.googleapis.com/v0/b/...someURL...",
},
"94f2-1494-908f-c17a-5adc": Object {
"url": "https://firebasestorage.googleapis.com/v0/b/...someURL...",
},
},
"posted": 1562901067,
"vote": 1,
},
}
I am able to render "author", "caption", "posted", and "vote" by using a Flatlist like so:
<FlatList
refreshing={this.state.refresh}
onRefresh={this.loadNew}
data={this.state.photo_feed}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item, index }) => (
<View key={index}>
<View>
<Text>{item.posted}</Text>
<Text>{item.author}</Text>
</View>
<View>
<Image
source={{ uri: item.photo }}
/>
</View>
<View>
<Text>{item.caption}</Text>
<View>
<View>
<Text>Votes: {item.vote}</Text>
</View>
</View>
</View>
</View>
)}
/>
but I don't understand how I can loop through the 3 "url" in "photo"
<View>
<Image
source={{ uri: item.photo }}
/>
</View>
^ doesn't load any image

You will need to loop over the photo object's values and create Image component for each of the photoItem inside. Something like this might work,
<View>
{
Object.values(item.photo).map(photoItem => (
<Image source={{ uri: photoItem.url }} />
))
}
</View>
Hope that helps!

Related

How to position left and right items when 3 items in a row?

In React Native 0.70 app, 2nd Header (react-native-element 3.4.2 is added to the view under the 1st Header with its centerComponent pointing to a search bar (one line only). Here is the code:
import { Header } from 'react-native-elements';
import { Col, Row, Grid } from 'react-native-easy-grid';
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen';
Bar = () => {. //<<==search element
return (
<View style={{position:"absolute", bottom:-hp("2.2%"), alignContent:"flex-start", paddingTop:hp("2.5%"),flexDirection:"row", wifth:"100%"}}>
<View style={{flex:1, alignItems:"center"}}>
<TouchableOpacity onPress={()=>{submit()}} >
<Icon name="search-outline" color="black" size={hp("4.4%")}/>
</TouchableOpacity>
</View>
<View style={{flex:8}}>
<TextInput placeholder={"plcholder"} onChangeText={strChg}></TextInput>
</View>
<View style={{flex:1, alignItems:"center"}}>
<TouchableOpacity onPress={()=>{navigation.navigate("MyHelp")}} >
<Icon name="help-outline" color="black" size={hp("4.4%")}/>
</TouchableOpacity>
</View>
</View>
)
}
return (
<View style={styles.container}>
<Header //<<== first header to show screen name
containerStyle={{backgroundColor: '#f4511e'}}
centerComponent={<HeaderCenter />}. //<<==show screen name
/>
<Header //<<==2nd header to show search bar
containerStyle={{backgroundColor: 'white'}} //<<==white background color
centerComponent={<Bar/>} //<<==here goes the search bar
/>
<ScrollView>
....
</ScrollView>
</View>
)
styles = StyleSheet.create({
container: {
flex:1
},
text: {
alignItems:'center',
alignContent:'center',
paddingTop:wp("20%"),
fontSize:wp("5%"),
},
}
Here is how the header bar looks:
The problem is 2 icons position. The icon on the left shall start from the left most and the icon on the right shall be at the far right. `alignContent:"flex-start/flex-end" on icon did not work. Increase TextInput flex to 10 cut off portion of 2 icons and did not push the icon away. How to move those 2 icons to their position?
just give justifyContent: 'space-between' and it will place left item to the left most and right item to the right most
The search bar was constructed on its own instead of using Header from react-native-elements. Here is the code:
return (
<View style={styles.container}>
<Header
containerStyle={{backgroundColor: '#f4511e'}}
centerComponent={<HeadCenter />}
/>
<View style={{ bottom:hp("0%"), alignContent:"space-between", paddingTop:hp("0.1%"),flexDirection:"row", width:"100%", height:hp("7%")}}>. //<<==this is the View bloc to hold search bar.
<View style={{flex:1, alignContent:"flex-start",justifyContent:"center",alignItems:"center"}}>
<Pressable onPress={()=>{submit()}} >
<Icon name="search-outline" color="black" size={hp("4.4%")}/>
</Pressable>
</View>
<View style={{flex:5}}>
<TextInput style={{fontSize:hp("3%")}} placeholder={plcholder} onChangeText={strChg}></TextInput>
</View>
<TouchableOpacity onPress={()=>{navigation.navigate("MyHelp")}} >
<View style={{flex:2, alignContent:"flex-start", justifyContent:"center",alignItems:"center"}}>
<Icon name="help-outline" color="black" size={hp("4.4%")}/>
</View>
</TouchableOpacity>
</View>
<ScrollView>
....
</ScrollView>
)

KeyboardAvoidingView not working properly on iOS react native, expo even if I tried all solutions including the documentation

I have a react native Expo project. Unfortunately I am blocked by an annoying problem.
This is how the view looks like:
When I click on the second input (Quantity) an empty blank space is added :(
Furthermore, when I click the second time on the input, the keyboard overlaps again
And this is the code:
<KeyboardAvoidingView style={{ flex: 1 }} behavior={"height"}>
<View style={style.container}>
<Header
title={t("shoppingList.title")}
view={AppView.SHOPPING_CART}
onDelete={() => setConfirmMultipleDeleteModalVisible(true)}
onSettings={() => setSettingsModalVisible(true)}
/>
<SettingsModal
visible={settingsModalVisible}
onSave={onSaveSettings}
onClose={() => setSettingsModalVisible(false)}
/>
<View style={{ flex: 1 }}>
<FlatList
data={shoppingList}
keyExtractor={(item, index) => index + ""}
ListHeaderComponent={
<ShoppingListTableHeader
columns={columns}
selectedColumn={selectedColumn}
direction={direction}
sort={sortTable}
/>
}
stickyHeaderIndices={[0]}
renderItem={({ item, index }) => {
return (
<GestureHandlerRootView>
<ConfirmMultipleDeleteModal
visible={confirmMultipleDeleteModalVisible}
items={shoppingList.filter(
(item) => selectedItemIds.indexOf(item.id) !== -1
)}
onDelete={multipleDeleteAndCloseConfirmModal}
onClose={() => setConfirmMultipleDeleteModalVisible(false)}
/>
<Pressable
onPress={() => {
handleOnPress(item);
mark(index);
}}
onLongPress={() => {
selectItems(item);
}}
>
<Card
style={{
...generalStyles.card,
backgroundColor: index % 2 == 1 ? "#F0F0F0" : "white",
}}
>
<View style={generalStyles.displayOnRow}>
{selectedItemIds.length > 0 && (
<Checkbox
status={
selectedItemIds.indexOf(item.id!) !== -1
? "checked"
: "unchecked"
}
onPress={() => handleOnPress(item)}
color={"#585858"}
uncheckedColor={"black"}
/>
)}
<ShoppingItem
item={item}
index={index}
marked={shoppingList[index].bought}
/>
</View>
{selectedItemIds.indexOf(item.id!) !== -1 && (
<View style={generalStyles.overlay} />
)}
</Card>
</Pressable>
</GestureHandlerRootView>
);
}}
/>
</View>
{addModalVisible ? (
<AddShoppingListItem
onSave={onSaveItem}
onClose={() => setAddModalVisible(false)}
/>
) : (
<MaterialCommunityIcons
name={"cart-plus"}
size={40}
onPress={() => setAddModalVisible(true)}
style={style.addIcon}
/>
)}
<StatusBar style="auto" />
</View>
</KeyboardAvoidingView>
export const style = StyleSheet.create({
container: {
flex: 1,
paddingTop: 40,
width: "100%",
}
});
I also tried to put the component inside
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={styles.container}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
but it didn't work :(
I am wondering ifit is related to the fact that I am using
createMaterialBottomTabNavigator();
Any suggestions, pleaseee?
The docs suggest using behavior='padding' on iOS. https://docs.expo.dev/versions/latest/react-native/keyboardavoidingview/
If that doesn't work for you, try experimenting with a negative keyboardVerticalOffset on the KeyboardAvoidingView.

Display Date from Firestore timestamp in Flatlist

I have a Flatlist to display data from Firestore, Flatlist render item as follows,
const Card = ({ item }) => (
<View style={styles.card}>
<View style={styles.itemDetails}>
<Text style={styles.itemTitle}>{item.title}</Text>
<Text style={styles.itemDescription}>{item.description}</Text>
</View>
<View style={styles.timerContainer}>
<Text style={styles.timer}>{item.expTime}</Text>
<Text style={styles.palceHolder}>Remaning Time</Text>
</View>
</View>
);
When I'm display time as above I got to following error
Can anyone help me to solve this problem.Thank you
The problem happens when you try to render an object inside the Text,
You will have to convert the date before showing it, try something like below.
const Card = ({ item }) => {
const time= new Date(
item.expTime.seconds * 1000 + item.expTime.nanoseconds / 1000000,
);
return (
<View style={styles.card}>
<View style={styles.itemDetails}>
<Text style={styles.itemTitle}>{item.title}</Text>
<Text style={styles.itemDescription}>{item.description}</Text>
</View>
<View style={styles.timerContainer}>
<Text style={styles.timer}>{time.toDateString()}</Text>
<Text style={styles.palceHolder}>Remaning Time</Text>
</View>
</View>
)};

How to set props fro dynamic value in styles in react native

I am getting data from server in which i have to set props in style sheet to change the background color dynamically. but i am getting an error
undefined is not an object (evaluating 'this.props.colorCode')
here is my code
class TopCategoryCard extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.CardMainView}>
<View style={styles.ThirdLayerStyle}>
</View>
<View style={styles.SecondLayerStyle}>
</View>
<View style={styles.FirstLayerStyle}>
<Image resizeMode={'contain'} style={styles.CatImageStyle}
source={this.props.imageUri}
/>
</View>
<Text numberOfLines={1} style={{color:'#fff' , fontSize:13, top:28 , marginLeft:25 , marginRight:20, fontFamily: "poppinsregular"}}>{this.props.name}</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
padding:5
},
CardMainView:{
flexDirection:'row',
borderRadius:4,
backgroundColor: this.props.colorCode,
height:80,
elevation:3,
shadowColor:'#000',
overflow:'hidden',
}
}
In the Above code i am getting the image and name successfully but facing error in changing the color code kindly help
color changing code
<ScrollView
style={{ marginTop:15 , marginLeft:-5 }}
horizontal={true}
showsHorizontalScrollIndicator={false}>
<FlatList
data={this.state.data}
keyExtractor={(x, i) => i.toString()}
renderItem={({ item }) => (
<TouchableOpacity
activeOpacity={0.9}
onPress={() =>
this.props.navigation.navigate(
"JobbyCategorylist",
{ slug: item.slug }
)
}
>
<TopCategoryCard
imageUri={{ uri: `${item.url}` }}
name={`${entities.decode(item.name)}`}
colorCode={item.color}
/>
</TouchableOpacity>
)}
horizontal={true}
/>
</ScrollView>
You cannot dynamically assign values to StyleSheet properties. Instead, you can try something like this:
<View style={[ styles.CardMainView, {backgroundColor: this.props.colorCode} ]}>
Don't forget to remove backgroundColor: this.props.colorCode from CardMainView.

How to add carousel for dynamic blocks from WordPress API in react native?

I am implementing react native app for woocommerce WordPress website. I need to add carousel for product images, price, name which is fetched from WordPress woocommerce API. The content from API is fetched and working fine but cannot integrate carousel.
What have I done yet?
render () {
const carr = <FlatList
data={this.state.data || []}
keyExtractor = {(x,i) =>i.toString()}
renderItem = {({item})=>
<Carousel
ref={(c) => { this._carousel = c; }}
renderItem={ <TouchableHighlight onPress={() => navigate("Products", { product: item })} underlayColor="transparent">
<View style={styles.view} >
<Image style={styles.image} source={{uri: item.images[0].src}} />
<Text style={styles.text}>{item.name}</Text>
<View style={styles.borderNow}></View>
<View style={styles.cartPrice}>
<Text style={styles.addCart}>₹{item.price}</Text>
<Text style={styles.price}>
</Text>
</View>
</View>
</TouchableHighlight>
}
sliderWidth={290}
itemWidth={290}
/>
} />
return (
<View>
{carr}
</View>
I used 'react-native-snap-carousel' this module and tried for sliding. But I get evaluating.data.length error . I am beginner in react.

Resources