firebase POST url 400 错误请求

IT技术 reactjs firebase post firebase-realtime-database crud
2022-07-23 01:51:38

我正在尝试使用一种非常简单的方法从我的 reactjs 应用程序向 firebase 实时数据库发布请求。这是一个进入我的数据库的屏幕截图。这里 blogs 下的第一个条目是用户的 UID,该用户可以创建多个博客,例如屏幕截图中的 id b1。Friebase DB url 和示例表条目

这是我的 POST 请求代码:

const id = localStorage.getItem('uid')
 const postData = async () => {
        var num = localStorage.getItem('blogNumber')
        const resp = await fetch(
            'https://assignment-c3557-default-rtdb.asia-southeast1.firebasedatabase.app.firebaseio.com/blogs.json',
            {
             method: 'POST',
             body: {
                id: {
                    num : {
                        title: titleRef.current.value,
                        description: contentRef.current.value,
                        createdAt: new Date(),
                        isPosted: false
                    }
                }
            },
            headers: {
                'Content-Type': 'application/json'
            }
            });
            const data = await resp.json()
           localStorage.setItem('blogNumber', localStorage.getItem('blogNumber') +1)
    }

尝试点击此网址时收到 400 个错误请求

但根据这个页面,这似乎是我正在点击的正确网址

https://retool.com/blog/your-guide-to-crud-in-firebase-realtimedb-with-rest-api/

1个回答

这里有很多问题:

  • 您没有在此处使用idor的值num,您需要将它们括在方括号中
  • API 调用的body属性fetch应该通过JSON.stringify.
  • 您不应在请求正文中发布 Date 对象。将其转换为字符串、将其转换为纯数字、使用时间戳对象或使用服务器值占位符。
  • 您的代码始终假定帖子已成功创建。fetchAPI 不会因错误的状态代码而引发错误您应该检查状态代码以确定您想要做什么。由于 Firebase 数据库操作通常以 JSON 响应,因此我在检查代码之前将此处的主体解析为 JSON,但是您可能应该先检查空主体。
  • 每次写入数据时,使用POST /blogs.json都会覆盖整个树。/blogs您应该更改路径或使用带有适当正文的 PATCH 请求。
const id = localStorage.getItem('uid')
const postData = async () => {
  const num = localStorage.getItem('blogNumber')
  const reqData = {
    [id]: { // <-- use square brackets for value as key
      [num]: { // <-- use square brackets for value as key
        title: titleRef.current.value,
        description: contentRef.current.value,
        createdAt: Date.now(), // <-- returns milliseconds since epoch
        isPosted: false
      }
    }
  }

  const resp = await fetch(
    'https://assignment-c3557-default-rtdb.asia-southeast1.firebasedatabase.app.firebaseio.com/blogs.json',
    {
      method: 'POST',
      body: JSON.stringify(reqData), // you need to stringify this yourself
      headers: {
        'Content-Type': 'application/json'
      }
    }
  );

  
  const data = await resp.json();

  if (!resp.ok) { // fetch API does not throw errors by itself
    const err = new Error('Unexpected status: ' + resp.status);
    err.data = data;
    err.resp = resp;
    throw err;
  }

  localStorage.setItem('blogNumber', localStorage.getItem('blogNumber')+1)
}

更新为使用更深的路径:

const id = localStorage.getItem('uid')
const postData = async () => {
  const num = localStorage.getItem('blogNumber')
  const reqData = {
    title: titleRef.current.value,
    description: contentRef.current.value,
    createdAt: Date.now(), // <-- returns milliseconds since epoch
    isPosted: false
  }

  const resp = await fetch(
    `https://assignment-c3557-default-rtdb.asia-southeast1.firebasedatabase.app.firebaseio.com/blogs/${uid}/${num}.json`,
    {
      method: 'POST',
      body: JSON.stringify(reqData), // you need to stringify this yourself
      headers: {
        'Content-Type': 'application/json'
      }
    }
  );
  
  const data = await resp.json();

  if (!resp.ok) { // fetch API does not throw errors by itself
    const err = new Error('Unexpected status: ' + resp.status);
    err.data = data;
    err.response = resp;
    throw err;
  }

  localStorage.setItem('blogNumber', localStorage.getItem('blogNumber')+1)
}