2017-08-11 40 views
3

我一直在探索这个firebase存储图像上传shenanigan。我卡住了。我如何去显示上传进度?我刚刚意识到使用状态不是可行的方式,因为我会一遍又一遍地调用setState。想法你会吗?React + Firebase存储+文件上传和进度显示

我想我需要某种递归函数,但是我在哪里调用它?我不能称之为承诺的内部吗?

// You'll need to set the rules to allow un-authed uploading however. 
 
// Here's how to allow public: goto your firebase console and select the storage tab then the rules tab and change to: 
 
// 
 
// service firebase.storage { 
 
// match /b/{bucket}/o { 
 
// match /{allPaths=**} { 
 
//  allow read, write; 
 
// } 
 
// } 
 
// } 
 
// 
 
// 
 
// I just threw together an infinite grow animation here for shits, however, I use styled components in my own app so I will access the this.state.percent value in the "actual" animation. 
 

 
const config = { 
 
    apiKey: "KEY", 
 
    authDomain: "DOMAIN", 
 
    databaseURL: "DB_URL", 
 
    projectId: "ID", 
 
    storageBucket: "BUCKET", 
 
    messagingSenderId: "MSG_ID" 
 
}; 
 

 
firebase.initializeApp(config); 
 
const storageRef = firebase.storage().ref() 
 

 
class App extends React.Component { 
 
    constructor() { 
 
    super() 
 
    this.state = { 
 
     uploading: false, 
 
     percent: 0, 
 
     file: '', 
 
     error: '' 
 
    } 
 
    this.handleFileSelect = this.handleFileSelect.bind(this) 
 
    this.handleFileUpload = this.handleFileUpload.bind(this) 
 
    } 
 
    handleFileSelect(e) { 
 
    this.setState({file: e.target.files[0]}) 
 
    } 
 
    handleFileUpload() { 
 
    this.setState({uploading: true}) 
 
    storageRef.child('images') 
 
     .put(this.state.file) 
 
     .then(snap => { 
 
     this.setState({uploading: false}) 
 
     // the loading percent logic here? 
 
     // how do i keep tabs on the percent? 
 
     }) 
 
     .catch(err => this.setState({error: err.message})) 
 
    } 
 
    render() { 
 
    return (
 
     <div className='container'> 
 
     <div className='form'> 
 
      <input type='file' onChange={this.handleFileSelect}/> 
 
      <button onClick={this.handleFileUpload}>Upload</button> 
 
     </div> 
 
     {this.state.uploading 
 
      ? <div> 
 
       <div className='load-bar'/> 
 
       <span>Uploading: {this.state.percent}%</span> 
 
      </div> 
 
      : '' 
 
     } 
 
     <pre> 
 
      <code> 
 
      {this.state.error ? <span className='error'>{this.state.error}</span> : ''} 
 
      {JSON.stringify(this.state.file, null, 2)} 
 
      </code> 
 
     </pre> 
 
     </div> 
 
    ) 
 
    } 
 
} 
 

 
ReactDOM.render(<App/>, document.getElementById('root'))
body { 
 
    background: #212121; 
 
    color: #dbdbdb; 
 
} 
 

 
.form { 
 
    display: flex; 
 
    justify-content: center; 
 
    align-items: center; 
 
    flex-direction: column; 
 
    padding: 1rem; 
 
    margin: 1rem; 
 
    background: rgba(0,0,0,0.4); 
 
} 
 

 
.error { 
 
    font-size: 14px; 
 
    text-align: center; 
 
    color: red; 
 
} 
 

 
.load-bar { 
 
    height: 20px; 
 
    width: 0px; 
 
    background: lime; 
 
    animation: grow 5s linear forwards; 
 
} 
 

 
@keyframes grow { 
 
    from { 
 
    width: 0px; 
 
    } 
 
    to { 
 
    width: 100%; 
 
    } 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
<script src="https://www.gstatic.com/firebasejs/4.2.0/firebase.js"></script> 
 

 
<div id='root'></div>

回答

4

最后发现,在火力文档(所有地方)的答案。去搞清楚。

这里的瘦米妮:

var uploadTask = storageRef.child('images/rivers.jpg').put(file); 

// Register three observers: 
// 1. 'state_changed' observer, called any time the state changes 
// 2. Error observer, called on failure 
// 3. Completion observer, called on successful completion 
uploadTask.on('state_changed', function(snapshot){ 
    // Observe state change events such as progress, pause, and resume 
    // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded 
    var progress = (snapshot.bytesTransferred/snapshot.totalBytes) * 100; 
    console.log('Upload is ' + progress + '% done'); 
    switch (snapshot.state) { 
    case firebase.storage.TaskState.PAUSED: // or 'paused' 
     console.log('Upload is paused'); 
     break; 
    case firebase.storage.TaskState.RUNNING: // or 'running' 
     console.log('Upload is running'); 
     break; 
    } 
}, function(error) { 
    // Handle unsuccessful uploads 
}, function() { 
    // Handle successful uploads on complete 
    // For instance, get the download URL: https://firebasestorage.googleapis.com/... 
    var downloadURL = uploadTask.snapshot.downloadURL; 
}); 

干杯。