我正在尝试将文件上传到firebase中,但是文件上传进度达到了100%,然后突然显示了一个未知错误,例如
{
"error": {
"code": 400,
"message": "Bad Request. Could not create object",
"status": "CREATE_OBJECT"
}
}
这是我用来上传文件的代码,这是完成文件上传的实际组件,用户打开一个模式以选择文件,然后在选择并按下模式中的send之后,文件上传开始在以下组件中。
import React, { Component } from "react";
import { Segment, Button, Input, ButtonGroup } from "semantic-ui-react";
import firebase from "../../firebase";
import FileModal from "./FileModal";
import uuidv4 from "uuid/v4";
class MessageForm extends Component {
state = {
storageRef: firebase.storage().ref(),
message: "",
channel: this.props.currentChannel,
user: this.props.currentUser,
loading: false,
errors: [],
modal: false,
uploadState: "",
uploadTask: null,
percentUploaded: 0
};
uploadFile = (file, metadata) => {
const pathToUpload = this.state.channel.id;
const ref = this.props.messagesRef;
const filePath = `chat/public/${uuidv4}.jpg`;
this.setState(
{
uploadState: "uploading",
uploadTask: this.state.storageRef.child(filePath).put(file, metadata)
},
() => {
this.state.uploadTask.on(
"state_changed",
snap => {
const percentUploaded = Math.round(
(snap.bytesTransferred / snap.totalBytes) * 100
);
this.setState({ percentUploaded });
},
err => {
console.error(err);
this.setState({
errors: [...this.state.errors, err],
uploadState: "error",
uploadTask: null
});
},
() => {
console.log(this.state.uploadTask);
this.state.uploadTask.snapshot.ref
.getDownloadURL()
.then(downloadUrl => {
this.sendFileMessage(downloadUrl, ref, pathToUpload);
})
.catch(err => {
console.error(err);
this.setState({
errors: [...this.state.errors, err],
uploadState: "error",
uploadTask: null
});
});
}
);
}
);
};
sendFileMessage = (fileUrl, ref, pathToUpload) => {
ref
.child(pathToUpload)
.push()
.set(this.createMessage(fileUrl))
.then(() => {
this.setState({
uploadState: "done"
}).catch(err => {
console.error(err);
this.setState({
errors: [...this.state.errors, err]
});
});
});
};
openModal = () => {
this.setState({
modal: true
});
};
closeModal = () => {
this.setState({
modal: false
});
};
handleChange = e => {
this.setState({
[e.target.name]: e.target.value
});
};
createMessage = (fileUrl = null) => {
const message = {
timestamp: firebase.database.ServerValue.TIMESTAMP,
user: {
id: this.state.user.uid,
name: this.state.user.displayName,
avatar: this.state.user.photoURL
}
};
if (fileUrl != null) {
message["image"] = fileUrl;
} else {
message["content"] = this.state.message.trim();
}
return message;
};
sendMessage = () => {
const { messagesRef } = this.props;
const { message, channel } = this.state;
if (message) {
this.setState({
loading: true
});
messagesRef
.child(channel.id)
.push()
.set(this.createMessage())
.then(() => {
this.setState({
loading: false,
message: "",
errors: []
});
})
.catch(err => {
console.error(err);
this.setState({
loading: false,
errors: [...this.state.errors, err]
});
});
} else {
this.setState({
errors: [...this.state.errors, { message: "Add a message" }]
});
}
};
render() {
const { errors, message, loading, modal } = this.state;
return (
<Segment className="message__form">
<Input
fluid
name="message"
style={{ marginBottom: "0.7em" }}
icon="add"
iconPosition="left"
placeholder="Write your message"
onChange={this.handleChange}
className={
errors.some(error => error.message.includes("message"))
? "error"
: ""
}
value={message}
/>
<ButtonGroup icon widths="2">
<Button
onClick={this.sendMessage}
disabled={loading}
color="orange"
content="Add reply"
labelPosition="left"
icon="edit"
/>
<Button
color="violet"
content="Upload Media"
labelPosition="right"
icon="cloud upload"
onClick={this.openModal}
/>
<FileModal
modal={modal}
closeModal={this.closeModal}
uploadFile={this.uploadFile}
/>
</ButtonGroup>
</Segment>
);
}
}
export default MessageForm;
答案 0 :(得分:0)
只是个猜测,但我怀疑您的错误可能与将uploadTask
存储在组件的state
中的方式有关...这让我非常不舒服-似乎违反了在React中使用组件状态的核心原则之一。
您可能已经听说过,状态只能通过setState
命令进行突变...而您的方法存在的问题是,状态将在执行上传过程中发生变化。实际上,您的代码就依赖它-您已经编写了它,以便在uploadTask
更新时,它的百分比就会显示在屏幕上。
总体来说,您有个正确的主意-只需将uploadTask
中的uploadTask: this.state.storageRef.child(filePath).put(file, metadata)
分派出去……就是这样:
state
(未经测试的代码,仅概念性)