NZMAI
NZMAI

Reputation: 546

React app: Images from firebase are not shown on a page

I want to display images on a page that come from firebase. I can successfully get urls from the storage but when I use them in image as a src, they (images) are not shown. enter image description here As you can see from the image above, image tags are blank. I don't know what is the problem. Could suggest me a way out. My code is the following:

import React, { Component } from 'react';
import { firebase } from '../../../firebase';
import AdminLayout from '../../../Hoc/AdminLayout';
import { firebasePhotos } from '../../../firebase';
import { firebaseLooper, reverseArray } from '../../ui/misc';
import { css } from 'react-emotion';
import { BarLoader } from 'react-spinners';
import { confirmAlert } from 'react-confirm-alert';
import 'react-confirm-alert/src/react-confirm-alert.css';

class Adminphoto extends Component {
  state = {
    isLoading: true,
    photos: [],
    marginTop: '40px',
    successForm: ''
  };

  componentDidMount() {
    firebasePhotos.once('value').then(snapshot => {
      const photos = firebaseLooper(snapshot);
      this.setState({
        isLoading: false,
        marginTop: '0px',
        photos: reverseArray(photos)
      });
    });
  }

  getURL = filename => {
    //console.log(filename);
    firebase
      .storage()
      .ref('photos')
      .child(filename)
      .getDownloadURL()
      .then(url => {
        console.log('url =>' + url);
        return url;
      });
  };

  successForm(message) {
    this.setState({
      successForm: message
    });

    setTimeout(() => {
      this.setState({
        formSuccess: ''
      });
    }, 2000);
  }

  deleteItem(event, photo) {
    event.preventDefault();
    confirmAlert({
      title: 'Confirm to submit',
      message: 'Are you sure to do this.',
      buttons: [
        {
          label: 'Yes',
          onClick: () => {
            firebasePhotos
              .child(photo.id)
              .remove()
              .then(() => {
                this.successForm('Removed successfully');
                this.props.history.push('/admin_photo');
              });
          }
        },
        {
          label: 'No',
          onClick: () => {
            return false;
          }
        }
      ]
    });
  }

  render() {
    console.log(this.state.photos);
    const override = css`
      display: block;
      margin: 0 auto;
      border-color: red;
    `;
    return (
      <AdminLayout>
        <React.Fragment>
          <div
            className="has-text-centered"
            style={{ marginTop: this.state.marginTop }}
          >
            {this.state.isLoading ? (
              <BarLoader
                className={override}
                sizeUnit={'px'}
                size={50}
                width={100}
                height={4}
                color={'#2D7969'}
                loading={this.state.loading}
              />
            ) : (
              ''
            )}
          </div>
          <div className="columns">
            {this.state.photos
              ? this.state.photos.map((photo, i) => (
                  <div key={i} className="column">
                    <img src={this.getURL(photo.image)} />
                  </div>
                ))
              : null}
          </div>
        </React.Fragment>
      </AdminLayout>
    );
  }
}

export default Adminphoto;

Upvotes: 0

Views: 1700

Answers (2)

Nikko Khresna
Nikko Khresna

Reputation: 1009

changes i made:
1. this.state.photos to be the img src
2. this.getURL() is called in componentDidMount()
3. <img> gets src directly from state

  componentDidMount() {
    firebasePhotos.once('value').then(snapshot => {
      const photos = firebaseLooper(snapshot);

      reverseArray(photos).map(photo => {
        this.getURL(photo.image)
      })

      this.setState({
        isLoading: false,
        marginTop: '0px',
      })
    });
  }

  getURL = filename => {
    //console.log(filename);
    firebase
      .storage()
      .ref('photos')
      .child(filename)
      .getDownloadURL()
      .then(url => {
        this.setState({ photos: [...this.state.photos, url] })
      });
  };

  render() {
  ...
              this.state.photos.map((photo, i) => (
                  <div key={i} className="column">
                    <img src={photo} />
                  </div>
                ))
  ...

hope it works, lemme know if im not really clear at explaining

Upvotes: 1

Umair Farooq
Umair Farooq

Reputation: 1833

One way to do this is to save url of image in the firebase realtime database and then get them from database and save them in the state.

You can manually save the urls in the database while uploading them or write cloud function triggers which will save urls in the database, every time image is uploaded in the firebase storage.

Upvotes: 1

Related Questions