reactjs - 为什么我在 React 应用程序中没有获取 Firebase 存储文件 url?

标签 reactjs firebase google-cloud-firestore firebase-storage

在我的 React 应用程序中,我主要有三个连接到 firebase 的功能。 firebase 身份验证、实时聊天,而这第三个需要 firebase 存储。我想上传带有聊天消息的图像。 当我尝试上传图像时,当我尝试 console.log(url)
时,控制台会给出此错误 我想获取下载的图像 url 并将其存储在我的 firestore 数据库中,然后在我的 Message.js 组件中使用该 url。 console shows me this error


我的 Chat.js 组件

  const [messages, setMessages] = useState([]);
  const [assets, setAssets] = useState(null);

  useEffect(() => {
    if (channelId) {
      db.collection("channels")
        .doc(channelId)
        .collection("messages")
        .orderBy("timestamp", "desc")
        .onSnapshot((snapshot) => {
          setMessages(snapshot.docs.map((doc) => doc.data()));
        });
    }
  }, [channelId]);

  const sendMessage = (e) => {
    e.preventDefault();
    const uploadTask = storage.ref(`assets_discord/${assets.name}`).put(assets);
    uploadTask.on("state_changed", () => { 
      storage
        .ref("assetsdiscord")
        .child(assets.name)
        .getDownloadURL()
        .then((url) => {
          db.collection("assetUrl").add({
            imgUrl: url,
          });
          console.log(url);
          setAssets(null);
        });
      });
      db.collection("channels").doc(channelId).collection("messages").add({
        user: user,
        message: input,
        timestamp: firebase.firestore.FieldValue.serverTimestamp(),
      });
      
    setInput("");
  };

  const hideInput = (e) => {
    e.preventDefault();
    setShowInput(!showInput);
  };

  return (
    <div className="chat">
      {channelId ? (
        <>
          <ChatHeader channelName={channelName} />
          <div className="chat__messages">
            {messages.map((message) => (
              <Message
                user={message.user}
                message={message.message}
                timestamp={message.timestamp}
                assetUrl={message.imgUrl}
              />
            ))}
          </div>
          <div className="chat__input">
            {showInput ? (
              <>
                <form action="#">
                  <label htmlFor="imgFiles" className="upload__img">
                    <AddCircle fontSize="large" />
                  </label>
                  <input
                    type="file"
                    id="imgFiles"
                    className="hidden"
                    accept="image/*"
                    onChange={(e) => {
                      if (e.target.files[0]) {
                        setAssets(e.target.files[0]);
                      }
                    }}
                  />
                  <input
                    disabled={!channelId}
                    value={input}
                    onChange={(e) => setInput(e.target.value)}
                    type="text"
                    placeholder={`Send Message to #${channelName}`}
                  />
                  <button
                    onClick={sendMessage}
                    className="chat__inputButton"
                    type="Submit"
                  >
                    Send Message
                  </button>
                  <button onClick={hideInput}>Hide</button>
                </form>
              </>
            ) : (
              <p
                onClick={() => setShowInput(!showInput)}
                className="show__input"
              >
                Show
              </p>
            )}
          </div>
        </>
      ) : (
        <>
          <div className="chat__selectRoom">
            <ArrowLeftIcon
              style={{ fontSize: "30px" }}
              className="arrow__left"
            />
            <h3>Select Any Room to get Started</h3>
          </div>
        </>
      )}
    </div>
  );

消息组件

const Message = ({ user, timestamp, message, assetUrl }) => {
  // console.log(assetUrl);
  return (
    <div className="message">
      <Avatar src={user.photo} />
      <div className="message__info">
        <h4>
          {user.displayName}
          <span className="message__timestamp">
            {new Date(timestamp?.toDate()).toUTCString()}
          </span>
        </h4>
        <p>{message}</p>
        {/*
         <ImageUpload assetUrl={assetUrl} /> 
       */}
        <img src={assetUrl} alt="dummy" />
      </div>
    </div>
  );
};

Firebase 安全性规则

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write;
    }
  }
}
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if true;
    }
  }
}

Link to live website

最佳答案

转到 Firebase 控制台,然后选择您正在处理的项目,然后转到存储,然后选择规则。

enter image description here

如果您使用 Firestore 或数据库,请检查规则。另一个问题可能是您尚未添加项目的 SHA。我们允许每个人更改存储方式的公共(public)访问。

就您的情况而言,正如您所评论的,问题可能是安全访问。 Here is a link to google documenations

我建议您在使用 Amazon AWS、Firebase 或任何类型的 API 等任何平台之前阅读文档。

再次检查 - 检查文件的地址,我重新检查了错误。您的安全规则是正确的,我认为您应该使用文档中的一些示例。

关于reactjs - 为什么我在 React 应用程序中没有获取 Firebase 存储文件 url?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67537825/

相关文章:

ios - 如何在字段包含字典数组的 firestore 上查询?

javascript - 如何设置 MUI 轮廓 TextField 的边框样式?

javascript - React 中的多个异步 XMLHttpRequest

firebase - 尝试从 firebase 获取单个文档时断言失败

javascript - 如何循环遍历我从 snapshot.val() 收到的数据并将其推送到基于键的数组

Javascript - 无法实例化 firebase-firestore

带有 AngularFire 的 Angular 拦截器

javascript - 为什么在 React Hooks 中排序后数据没有更新?

javascript - Redux mapStateToProps 返回未定义

ios - 为什么在 Firebase removeValue() 中删除数据不起作用?