fris-fruitig / react-firebase-file-uploader

An image uploader for react that uploads images to your firebase storage
https://npm.im/react-firebase-file-uploader
166 stars 45 forks source link

How can i show images locally before uploading them on firebase ? #19

Closed zainmustafa closed 5 years ago

zainmustafa commented 6 years ago

I'm using this library to upload images to firebase using react, it works perfectly fine with single or multiple images.

i'd like to if i can show images before uploading them on firebase. @oliversisson @kevinmcalear @arthurvi @sprmn

TIA

sprmn commented 6 years ago

Hi @zainmustafa, thanks for your question. It would be nice to have such an example in the documentation.

You could do something as suggested here on stackoverflow and use URL.createObjectURL on the image. Please note that this function is not supported on older browsers (<IE10).

To make sure the image only uploads after submitting, you'll have to do something similar to this.

Here is a quick example (without upload):

Edit 2pl2rrkoon

zainmustafa commented 6 years ago

Thanks, i'll create a pr for example.

MichaelDimmitt commented 5 years ago

@zainmustafa, was there a pr created for this feature? Posting that in this issue would be useful. Just specify the # num.

MichaelDimmitt commented 5 years ago

@sprmn, thanks for the CodeSandBox example: https://codesandbox.io/s/2pl2rrkoon

I was able to show the local image inside the handleUploadStart function! The trick was that handleUploadStart did not send the event. Rather it sent the file it resolved from event. To clarify, not: (event.target.files[0]) instead it was just (image)

Additionally,

example below:

const getUrl = (filename) => {
  let url;
  if (filename) {
    url = `https://firebasestorage.googleapis.com/v0/b/${process.env.REACT_APP_FIREBASE_STORAGE_BUCKET}/o/images%2F${uid}.jpg?alt=media`;
  } else { url = ''; }
  return url;
};

class App extends React.Component {
constructor(props){
  super(props);
  let profilePic = user && profilePictureHelper.getUrl(this.props.userName);
  this.state = {
    imageStatus: false,
    showPicture: true,
    profilePic
  };
}

handleChangeUsername = event =>
  this.setState({ username: event.target.value });

handleUploadStart = (e) => {
  const base64=URL.createObjectURL(e)
  if (e) {
    this.setState({ 
      profilePic: base64,
      showPicture: true, 
      imageStatus:false, 
      isUploading: true, progress: 0 });
  }
}
handleProgress = progress => this.setState({ progress });
handleUploadError = error => {
  console.error(error);
  this.setState({ isUploading: false });
};
handleUploadSuccess = filename => {
  this.setState({ avatar: filename, progress: 100, isUploading: false });
  firebase
    .storage()
    .ref("images")
    .child(userName)
    .getDownloadURL()
    .then(url => 
      this.setState({ 
        profilePic: url,
        showPicture: true, 
        imageStatus:true 
      })
    );
};

render(){
  return(
    <div>
      <img src={profilePic} 
        onLoad={()=>this.handleImageLoaded()} 
        onError={()=>this.noImageFound()}
      />

      <FileUploader
        accept="image/*"
        name="avatar"
        filename={`${userName}.jpg`} {/* hardcode .jpg file extension*/}
        storageRef={firebase.storage().ref("images")}
        onUploadStart={this.handleUploadStart}
        onUploadError={this.handleUploadError}
        onUploadSuccess={this.handleUploadSuccess}
        onProgress={this.handleProgress}  
      />
      {this.state.imageStatus ?
        <div>
          { this.state.isUploading && <p>Uploading: {this.state.progress}</p> }
          <StuffBelowImage/>
        </div>
        : <div></div>
      }
    </div>
  )
}