Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/431.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何将Firebase关系查询移动到服务器端_Javascript_Firebase_Firebase Realtime Database_Promise_React Redux - Fatal编程技术网

Javascript 如何将Firebase关系查询移动到服务器端

Javascript 如何将Firebase关系查询移动到服务器端,javascript,firebase,firebase-realtime-database,promise,react-redux,Javascript,Firebase,Firebase Realtime Database,Promise,React Redux,这是我在Firebase的第一个项目,我创建了一个关系数据结构。现在我明白为什么这不是最好的做事方式了 在我的应用程序的这一部分中,用户可以将多个项目添加到一套装备中——下面是我现在在Firebase中的数据结构/关系图 我已将Redux操作创建者的代码包含在我的React本机应用程序中。当用户编辑装备-删除某些项目-此代码: 从客户端获取包含新项目列表的数组 将此阵列与服务器端当前保存的项目进行比较 创建一个新的差异数组(已删除项) 循环浏览每个项目的装备,与正在编辑的装备匹配 删除匹配的引

这是我在Firebase的第一个项目,我创建了一个关系数据结构。现在我明白为什么这不是最好的做事方式了

在我的应用程序的这一部分中,用户可以将多个项目添加到一套装备中——下面是我现在在Firebase中的数据结构/关系图

我已将Redux操作创建者的代码包含在我的React本机应用程序中。当用户编辑装备-删除某些项目-此代码:

  • 从客户端获取包含新项目列表的数组
  • 将此阵列与服务器端当前保存的项目进行比较
  • 创建一个新的差异数组(已删除项)
  • 循环浏览每个项目的
    装备
    ,与正在编辑的装备匹配
  • 删除匹配的引用
  • 这段代码可以工作,但嵌套得很深,很混乱:

    export const updateTagReferences = (localTags, outfitId) => {
        //localTags represents the new set of items from application state
        //outfitId is the uid for the outfit where those items appear
      const {currentUser} = firebase.auth();
      return dispatch => {
        firebase
          .database()
          .ref(`users/${currentUser.uid}/outfits/${outfitId}/taggedItems`)
          .once('value')
          .then(snapshot => {
            var serverTags = snapshot.val();
                // Work out the diff (ie, which items have been removed locally)
            return _.differenceWith(serverTags, localTags, _.isEqual);
          })
          .then(toDelete => {
            toDelete.map(item => {
              firebase
                .database()
                .ref(`users/${currentUser.uid}/items/${item.item.uid}/outfits`)
                .once('value')
                .then(snapshot => {
                  var outfits = snapshot.val();
                  for (var taggedItem in outfits) {
                    if (outfits.hasOwnProperty(taggedItem)) {
                      var i = outfits[taggedItem];
                      return i.uid === outfitId
                        ? firebase
                            .database()
                            .ref(
                              `users/${currentUser.uid}/items/${item.item.uid}/outfits/${taggedItem}`,
                            )
                            .remove()
                        : null;
                    }
                  }
                });
            });
          })
          .then(console.log('Done'));
      };
    };
    
    如您所见,我正试图使用Firebase promises循环遍历嵌套在每个项目服务器端的
    装备

    我的问题是:

    • 我对Firebase进行了很多查询,这并不理想

    • console.log('Done')
      之前激发。remove()
      -此操作完成后,我需要执行第二个操作

    基于,我尝试了以下代码,但似乎无法使其正常工作:

    export const updateTagReferences = (localTags, outfitId) => {
      const {currentUser} = firebase.auth();
      return dispatch => {
        // Create a ref for the outfit the user is editing
        firebase
          .database()
          .ref(`users/${currentUser.uid}/outfits/${outfitId}/taggedItems`)
          .once('value')
          .then(snapshot => {
            // Compare local (app state) with remote (Firebase) to work out which items have been removed
            var serverTags = snapshot.val();
            return _.differenceWith(serverTags, localTags, _.isEqual);
          })
          .then(toDelete => {
            var promises = [];
            // Create a ref for each item to delete
            toDelete.map(item => {
              firebase
                .database()
                .ref(`users/${currentUser.uid}/items/${item.item.uid}/outfits`)
                .once('value')
                .then(snapshot => {
                  var outfits = snapshot.val();
                  for (var taggedItem in outfits) {
                    // Loop through the outfits that item appears in
                    if (outfits.hasOwnProperty(taggedItem)) {
                      var i = outfits[taggedItem];
                      // Match against the outfit the user is editing
                      return i.uid === outfitId
                        ? promises.push(
                            firebase
                              .database()
                              .ref(
                                `users/${currentUser.uid}/items/${item.item.uid}/outfits/${taggedItem}`,
                              )
                              // Remove the reference
                              .remove(),
                          )
                        : null;
                    }
                  }
                })
                // Execute all the promises, removing firebase references for each item removed locally
                .then(Promise.all(promises).then(console.log('Done')));
            });
          });
      };
    };
    
    我试图使我的代码总体上更高效,这样我就可以在我的项目中的其他地方复制它。我想解释一下移动这种查询服务器端的最佳方式

    目前,更改整个数据结构已超出范围(这是下一次!)


    谢谢。

    尝试
    返回Promise.all(promises)。然后(()=>console.log('done1')
    promises.push()
    返回数组的新长度,而不是刚刚添加的元素?需要修复。抱歉-我已更新了第一个代码块。我无意中发布了以前的版本。您需要原始代码中的
    promises
    数组和
    Promise.all(promises)
    等。不清楚您试图使用对象
    I
    及其属性
    I.uid
    实现什么。应该为
    i.uid
    分配什么?该值来自何处?那么
    i
    会发生什么呢,还有什么事情依赖于它吗?