Home > Software engineering >  listAll from firebase the getDownloadURL to store in Array to render FlatList of Images doen't
listAll from firebase the getDownloadURL to store in Array to render FlatList of Images doen't

Time:03-04

In my react native component I try to get a list of all images in my firebase store:

listAll(listRef).then((res) => {       
        res.items.forEach((itemRef) => {

For each image I do the getDownloadURL:

 const downloadUrl = getDownloadURL(ref(storage, itemRef))

Slice the token (for key later), create an object and push this object into an array:

downloadUrl.then((url) => {
                // Find token in url
                const indexOfToken = url.indexOf("&token=")

                // slice token from url [ 7 is the length of the word '&token=']
                const token = url.slice(indexOfToken   7)

                // create a image object
                const image = {
                    "imageUrl": url,
                    "imageToken": token
                }

                // store the image in eventImages array
                eventImages.push(image);

If I try to render a flatlist with this array.

<FlatList data={imageData}
   keyExtractor={item => item.imageToken}
   renderItem={({ item }) => (                      
     <Image style={{ marginRight: 2, marginTop: 2, width: '50%', opacity: 1 }} 
     source={{ uri: imageData.imageUrl }} alt="Alternate Text" size="xl" />
     )}/>

The Array is empty. Why?


Fullcode

import React, { useState } from 'react'
import { StyleSheet, SafeAreaView } from 'react-native'
import { Image, FlatList } from "native-base"
import EventGalleryHeader from '../components/EventGalleryHeader.js'
import { getStorage, ref, getDownloadURL, list, listAll } from "firebase/storage"
import { LongPressGestureHandler, State } from 'react-native-gesture-handler'

export default function EventScreen(props) {

    const [imageData, setImageData] = useState();
    const eventImages = []
    const storage = getStorage();
    const listRef = ref(storage, '/eventimages/1645351776501/');

    listAll(listRef).then((res) => {
        res.items.forEach((itemRef) => {
            const downloadUrl = getDownloadURL(ref(storage, itemRef))
            downloadUrl.then((url) => {
                const indexOfToken = url.indexOf("&token=")
                const token = url.slice(indexOfToken   7)
                const image = {
                    "imageUrl": url,
                    "imageToken": token
                }
                eventImages.push(image);
            }).catch((error) => {
                switch (error.code) {
                    case 'storage/object-not-found':
                        break;
                    case 'storage/unauthorized':
                        break;
                    case 'storage/canceled':
                        break;
                    case 'storage/unknown':
                        break;
                }
            });
            console.log(eventImages)
        });
    }).catch((error) => {
    });

    const onLongPress = (event) => {
        if (event.nativeEvent.state === State.ACTIVE) {
            alert("I've been pressed for 800 milliseconds");
        }
    };
    return (
        <SafeAreaView style={styles.container} >
            <FlatList _dark={{ bg: "blueGray.900" }} _light={{ bg: "blueGray.50" }}
                style={styles.list}
                numColumns={2}
                ListHeaderComponent={<EventGalleryHeader data={props.route.params.eventData} />}
                data={imageData}
                keyExtractor={item => item.imageToken}
                renderItem={({ item }) => (
                    <LongPressGestureHandler
                        onHandlerStateChange={onLongPress}
                        minDurationMs={800}
                    >
                        <Image style={{ marginRight: 2, marginTop: 2, width: '50%', opacity: 1 }} source={{ uri: imageData.imageUrl }} alt="Alternate Text" size="xl" />
                    </LongPressGestureHandler>
                )}
            />
        </SafeAreaView>
    );
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        marginTop: 25,
    },
    image: {
        maxHeight: 450,
        width: '100%',
        height: 200,
        overflow: 'hidden',
    },
    list: {
        alignSelf: 'center',
    },
    gallery: {
        flex: 1,
        width: '100%',
        flexDirection: 'row',

    }
})

CodePudding user response:

I think you are not adding the images to the imageData state

listAll(listRef).then((res) => {
    res.items.forEach((itemRef) => {
        const downloadUrl = getDownloadURL(ref(storage, itemRef))
        downloadUrl.then((url) => {
            const indexOfToken = url.indexOf("&token=")
            const token = url.slice(indexOfToken   7)
            const image = {
                "imageUrl": url,
                "imageToken": token
            }
            eventImages.push(image);
        }).catch((error) => {
            switch (error.code) {
                case 'storage/object-not-found':
                    break;
                case 'storage/unauthorized':
                    break;
                case 'storage/canceled':
                    break;
                case 'storage/unknown':
                    break;
            }
        });
        console.log(eventImages)
        setImageData(eventImages) // <---- Add the images to the imageData state
    });
}).catch((error) => {
});

CodePudding user response:

I've reconsidered my code and was wrong. Hopefully normal for a beginner.

Here is my working coder to load a gallery directly from Google Fireabase Store.

import React, { Component } from 'react'
import { StyleSheet, SafeAreaView } from 'react-native'
import { Image, FlatList } from "native-base"
import EventGalleryHeader from '../components/EventGalleryHeader.js'
import { getStorage, ref, getDownloadURL, list, listAll } from "firebase/storage"
import { LongPressGestureHandler, State } from 'react-native-gesture-handler'

export default class EventScreen extends Component {

    constructor(props) {
        super(props);
        this.storage = getStorage()
        this.pathToImages = '/eventimages/'
        this.eventImageSource = this.props.route.params.eventData.key
        this.imagesRef = this.pathToImages   this.eventImageSource
        this.state = {
            isLoading: true,
            images: [],
            event: {
                adress: this.props.route.params.eventData.adress,
                hosts: this.props.route.params.eventData.hosts,
                description: this.props.route.params.eventData.description,
                eventtitle: this.props.route.params.eventData.eventtitle,
                invitecode: this.props.route.params.eventData.invitecode,
                key: this.props.route.params.eventData.key,
                timestamp: this.props.route.params.eventData.timestamp,
            }
        }
    }

    componentDidMount() {
        this.getEventImageData()
    }

    componentWillUnmount() {
    }

    getEventImageData() {
        const images = []
        const event = {
            adress: this.props.route.params.eventData.adress,
            description: this.props.route.params.eventData.description,
            eventtitle: this.props.route.params.eventData.eventtitle,
            key: this.props.route.params.eventData.key,
            timestamp: this.props.route.params.eventData.timestamp,
        }

        listAll(ref(this.storage, this.imagesRef))
            .then((res) => {
                res.items.forEach((itemRef) => {
                    // console.log(itemRef._location.path_)

                    getDownloadURL(itemRef)
                        .then((url) => {

                            const indexOfToken = url.indexOf("&token=")
                            const token = url.slice(indexOfToken   7)
                            images.push({
                                "imageUrl": url,
                                "imageToken": token
                            });
                            this.setState({
                                images,
                                isLoading: false,
                                event
                            });
                            // console.log(this.state.images)
                        })
                        .catch((error) => {
                            switch (error.code) {
                                case 'storage/object-not-found':
                                    break;
                                case 'storage/unauthorized':
                                    break;
                                case 'storage/canceled':
                                    break;
                                case 'storage/unknown':
                                    break;
                            }
                        });


                });

            }).catch((error) => {
            });

    }


    onLongPress = (event) => {
        if (event.nativeEvent.state === State.ACTIVE) {
            alert("I've been pressed for 800 milliseconds");
        }
    };



    render() {

        return (
            <SafeAreaView style={styles.container} >
                <FlatList _dark={{ bg: "blueGray.900" }} _light={{ bg: "blueGray.50" }}
                    style={styles.list}
                    numColumns={2}
                    ListHeaderComponent={<EventGalleryHeader data={this.state.event} />}
                    data={this.state.images}
                    keyExtractor={item => item.imageToken}
                    renderItem={({ item }) => (
                        <LongPressGestureHandler
                            onHandlerStateChange={this.onLongPress}
                            minDurationMs={800}
                        >
                            <Image style={{ marginRight: 2, marginTop: 2, width: '50%', opacity: 1 }} source={{ uri: item.imageUrl }} alt="Alternate Text" size="xl" />
                        </LongPressGestureHandler>
                    )}
                />
            </SafeAreaView>
        );

    };

}
const styles = StyleSheet.create({
    container: {
        flex: 1,
        marginTop: 25,

    },
    image: {
        maxHeight: 450,
        width: '100%',
        height: 200,
        overflow: 'hidden',
    },
    list: {
        alignSelf: 'center',
    },
    gallery: {
        flex: 1,
        width: '100%',
        flexDirection: 'row',

    }
})
  • Related