【问题标题】:Firebase Realtime Database, only send data if the key && date don't existsFirebase 实时数据库,仅在键 && 日期不存在时发送数据
【发布时间】:2020-10-29 13:59:09
【问题描述】:

我做了很多研究并阅读了 firebase 上的多个 stackoverflow 问题。有些是有帮助的。但没有一个对我的问题特别有帮助。我正在尝试制作菜单计划器。例如,我需要不止一项检查来测试是否。日期存在,serviceType === to "lunch" || “晚餐”。

我有一个添加和图像保存 url 和输入数据到反应状态的功能。然后我使用 useEffect 来监听状态更新并将数据发送到 firebase。我只想将新数据发送到 firebase IF 所有的检查都通过并且它们不存在。否则我想更新我的数据。我试过了。 Foreach, for in, ref('link/'+ localState.id)。许多不同的方法我似乎无法正确。

这是表单提交功能:

const handleSubmit = (e) => {
    e.preventDefault();

    if (image) {
      const uploadTask = storage.ref(`images/${image.name}`).put(image);

      uploadTask.on(
        "state_changed",
        (snapshot) => {
          const progress = Math.round(
            (snapshot.bytesTransferred / snapshot.totalBytes) * 100
          );

          setProgress(progress);
        },
        (error) => {
          setError(error);
        },
        () => {
          storage
            .ref("images")
            .child(image.name)
            .getDownloadURL()
            .then((url) => {
              const value = state.serviceType;
              const keys = Object.keys(value);
              var filtered = keys.filter(function (key) {
                return value[key];
              });

/////////I have also tried this method, to use one function for all instead of using useEffect//////

              const mealData = db().ref().child("meals");
              const newMealdata = mealData.push();
              //  newMealdata.set({
              //    serviceId: newMealdata.key,
              //    date: props.dates,
              //    serviceType: filtered,
              //    service: {
              //      mealService: state,
              //      image: url,
              //    },
              //  });
///////////////////////////////////////////////

              setNewState((prev) => {
                return {
                  ...newState,
                  date: props.dates,
                  serviceType: filtered,
                  serviceId: newMealdata.key,
                  service: state,
                };
              });

              setProgress(0);
            });
        }
      );
    } else {
      setError("Error Please Choose an Image to Upload");
    }
  };

使用效果函数

 useEffect(() => {
    console.log("newState mounterd: ", newState);
    db()
      .ref("meals/" + newState.serviceId)
      .set({ newState });
  }, [newState]);

我尝试使用 state.id 来检查它是否等于 snapshot.key,尽管他们确实检查过。 firebase 仍然会创建一个新的数据节点,该节点具有相同的日期,但具有不同的 Id 和我想要更新的数据。

那么最好怎么说:

if(snapshot.val().date === props.dates && snapshot.val().serviceId === snapshot.key && servicetype === "lunch" || 'dinner'){
update({with new inserted data})
}else if(data doesn't match){
ref('meals').set({createNewNode})
}

【问题讨论】:

    标签: javascript reactjs firebase firebase-realtime-database


    【解决方案1】:

    Firebase 数据库实现了相当有限的查询支持。要扩展它,您通常必须:

    1. 扩展/修改您的数据模型以允许您想要的查询
    2. 在客户端代码或其他系统(例如专用的全文搜索引擎)中执行部分过滤。

    没有办法在实时数据库的查询中实现您的条件,因为:

    • 每个查询只支持一个条件。
    • 不支持 OR 条件。

    您有时可以将多个 AND 条件组合成一个查询,方法是向您的数据添加综合属性,例如 "dates_serviceId": "..._..."。有了这样的属性,您就可以查询ref.orderBy("dates_serviceId").equalTo("myDate_myServiceId")

    为了能够查询提供午餐或晚餐服务的节点,您必须扩展数据模型以显式识别此类节点,例如向它们添加 "lunch_or_dinner": true 属性。有了这样一个节点,就可以查询:ref.orderBy("lunch_or_dinner").equalTo(true)

    通过结合这两种方法,您甚至可以为整个查询创建一个属性 (dates_serviceId_lunch-or-dinner),尽管我必须承认,即使我的口味,这也变得有点过于具体了。

    【讨论】:

    • 通过在本地这样做,我觉得“这不是最佳实践”。我曾经做过某种工作,但我不记得我是如何做到的。但这就像将获取的数据保存到一个状态中一样。然后将该州与我当地的州进行比较。但不是使用 push 方法来获取随机密钥。我通过添加日期 + serviceType 创建了密钥。所以在firebase中,每个新孩子都有类似的东西。 10/29/20 午餐:{}或 10/29/20 晚餐:{}。我设法以这种方式编辑孩子,但我将 axios 用于 firebase。同样,不确定这样做是否明智。
    猜你喜欢
    • 1970-01-01
    • 2018-08-15
    • 2021-08-20
    • 2021-10-23
    • 2017-10-24
    • 2016-10-17
    • 2020-12-24
    • 2019-08-10
    • 2020-03-21
    相关资源
    最近更新 更多