【问题标题】:Saving structured data in firebase with angular使用角度将结构化数据保存在firebase中
【发布时间】:2016-06-28 03:18:34
【问题描述】:

我了解在 firebase 中保存 structured data 的概念和最佳实践,但我不清楚如何将数据实际保存到多个位置并提供所需的交叉引用。

{
  articles: {
    -KBX5TurV9uJTeiR26-N: {
       title: 'post title 1',
       body: 'post body goes here',
       imagesRef: {
          -KBX5XOYASP7h2ZPOKmg: true
       }
    },
    -KCe7cy6QC29WRYap0D1: {
       title: 'post title 2',
       body: 'post body goes here',
       imagesRef: {
          -KBX5XOYASP7h2ZPOKmg: true
       }
    }
  }
  images: {
    -KBX5XOYASP7h2ZPOKmg: {
       image: 'data:image/gif;base64,R0lGODlhZABkAOYAAPj4...',
       articlesRef: {
          -KBX5TurV9uJTeiR26-N: true,
          -KCe7cy6QC29WRYap0D1: true
       }
    }
  }
}

上面的架构是我想要的一个例子。在提交由标题、正文和图像字段组成的表单时,我需要将标题和正文发布到文章对象,然后将图像发布到图像对象,然后使用交叉引用更新 imagesRef 和articlesRef 对象。在 Angular 中解决这个问题的最佳方法是什么。我也有 angularfire 作为项目的一部分。

我是 angular 和 firebase 的新手,但我认为我需要做两篇文章,一篇是文章,一篇是图片,以保存它们并生成唯一的 ID。然后我需要一些如何等待两者都成功,获取唯一 ID 并在两个对象上执行和更新以保存交叉引用。到目前为止,这是我所拥有的,但不知道如何更进一步......

     $scope.AddPost = function(){

        var ref = new Firebase(FIREBASE_URI);
        var newArticleRef = ref.child('articles').push();
        var newArticleKey = newArticleRef.key();

        // Create the data we want to update
        var addNewPost = {};
        addNewPost["articles/" + newArticleKey] = {
            title:   $scope.article.title,
            post:    $scope.article.post
        };

        if ($scope.image) {

            var newImageRef = ref.child('images').push();
            var newImageKey = newImageRef.key();

            // Add image...
            addNewPost['images/' + newImageKey] = {
                image: $scope.image
            };

            //Add article ref...
            addNewPost['images/' + newImageKey + '/articles/' + newArticleKey] = true;

            //Add cross ref to article...
            addNewPost['articles/' + newArticleKey + '/image/' + newImageKey] = true;

        }


        // Do a deep-path update
        ref.update(addNewPost, function(error) {
                if (error) {
                    console.log("Error:", error);
                }
        });

    });

更新:我更新了代码示例以使用 multi-location updatesfan-out approach,但保存时出现错误...

Error: Firebase.update failed: First argument contains a path /images/-KCpx-Pj9oMM-EWN9irS that is ancestor of another path /images/-KCpx-Pj9oMM-EWN9irS/articles/-KCpx-Pj9oMM-EWN9irR
at Error (native)
at ig (http://localhost:8000/app/assets/js/plugins.js:430:390)
at jg (http://localhost:8000/app/assets/js/plugins.js:431:383)
at X.update (http://localhost:8000/app/assets/js/plugins.js:564:369)
at r.$scope.AddPost (http://localhost:8000/app/assets/js/app.js:171:17)
at fn (eval at <anonymous> (http://localhost:8000/app/assets/js/plugins.js:216:110), <anonymous>:4:212)
at e (http://localhost:8000/app/assets/js/plugins.js:257:177)
at r.$eval (http://localhost:8000/app/assets/js/plugins.js:133:446)
at r.$apply (http://localhost:8000/app/assets/js/plugins.js:134:175)
at r.scopePrototype.$apply (chrome-extension://ighdmehidhipcmcojjgiloacoafjmpfk/dist/hint.js:1427:22)

警告:我尝试了以下方法。它创建了一个对象并且没有触发 JS 错误,但是它清除了我的数据库,只留下了新创建的对象。没有损失太多,因为我现在只是在运行一些测试,但认为我应该警告其他人。不要这样做...

        addNewPost.Articles = {};
        addNewPost.Articles[newArticleKey] = {};
        addNewPost.Articles[newArticleKey].title = $scope.article.title;
        addNewPost.Articles[newArticleKey].post = $scope.article.post;

        var newImageRef = ref.child('images').push();
        var newImageKey = newImageRef.key();

        addNewPost.images = {};
        addNewPost.images[newImageKey] = {};
        addNewPost.images[newImageKey].image = $scope.image;
        addNewPost.images[newImageKey].articles = {};
        addNewPost.images[newImageKey].articles[newArticleKey] = true;

        addNewPost.Articles[newArticleKey].image = {};
        addNewPost.Articles[newArticleKey].image[newImageKey] = true;

【问题讨论】:

  • 感谢@FrankvanPuffelen,这似乎正是我想要的。我尝试将其插入,但现在我得到第一个参数包含路径,这是另一个路径错误的祖先。我错过了什么吗?
  • 表示更新中有两条重叠的路径。例如。 "/posts/bla": { body: "Nanana", title: "Blablabla" }"/posts/bla/author" : auth.uid。您要么需要将更新合并到一个路径中,要么将它们拆分为所有单独的属性。顺便说一句,这是一个完全独立的问题。
  • 是的,抱歉,我曾讨论过将其拆分为一个新问题。我将其保留为该线程的一部分,因为我仍在尝试找到使用 angular 将结构化数据保存在 firebase 中的解决方案。您提供的文章似乎是一个答案,但我无法以我上面提到的所需格式成功保存数据。
  • @FrankvanPuffelen 如果您想发布上面的链接作为答案,我可以给您信用。否则我会坚持下去,看看是否有人提出比我在下面发布的更好的选择。

标签: javascript angularjs firebase firebase-realtime-database angularfire


【解决方案1】:

不确定它是最佳答案,但我发现以下内容对我有用。它利用了 Frank van Puffelen 的建议来使用多位置更新。以下代码设置为支持添加新图像,使用现有图像或根本不使用图像。我认为这同样适用于类别、标签或用户中的任何元数据。

    .controller('AddPostController', ['$scope','$firebaseArray','FIREBASE_URI',
    function($scope,$firebaseArray,FIREBASE_URI) {

        var ref = new Firebase(FIREBASE_URI);

        $scope.AddPost = function(){

            var newArticleRef = ref.child('articles').push();
            var newArticleKey = newArticleRef.key();

            var newImageRef = ref.child('images').push();
            var newImageKey = newImageRef.key();

            // Create the data we want to update
            var addNewPost = {};

            // Add new article...
            addNewPost["articles/" + newArticleKey] = {
                title:   $scope.article.title,
                post:    $scope.article.post,
                emailId: user,
                '.priority': user
            };

            if ($scope.image) {

                // Add new image reference to new article...
                addNewPost["articles/" + newArticleKey].image = {};
                addNewPost["articles/" + newArticleKey].image[newImageKey] = true;

                // Add new image...
                addNewPost['images/' + newImageKey] = {
                    image: $scope.image,
                    emailId: user,
                    '.priority': user
                };

                // Add article reference to new image...
                addNewPost['images/' + newImageKey].articles = {};
                addNewPost['images/' + newImageKey].articles[newArticleKey] = true;

            } else if ($scope.article.image) {

                // Add existing image reference to article...
                addNewPost["articles/" + newArticleKey].image = {};
                addNewPost["articles/" + newArticleKey].image[$scope.article.image] = true;

                // Add new article reference to existing image...
                addNewPost['images/' + $scope.article.image + '/articles/' + newArticleKey] = true;

            }

            // Do a deep-path update
            ref.update(addNewPost, function(error) {
                if (error) {
                    console.log("Error:", error);
                }
            });

        };

    }]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-06
    • 2020-02-28
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-06
    相关资源
    最近更新 更多