关于这个主题和ChildEventListener的类似问题,没有相关的答案,所以这是我的。
我有一个保存所有数据的本地 SQLite 数据库,我还有一个 Firebase 实时数据库,我正在更新所有用户的新条目或实时更改。我目前正在使用 ChildEventListener 进行操作,如下所示:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getDatabase().getReference();
DatabaseReference childRef = rootRef.child("my_root");
ChildEventListener eventListener = new ChildEventListener()
{
....
};
childRef.addChildEventListener(eventListener);
至于功能,使用这段代码我可以实时更改子项、获取新条目、删除子项以及我需要的一切,但有一个问题。当此特定 Activity 与监听器一起加载时,onChildAdded 监听器会为此根上的每个子项调用大量次数,如文档中所述:
child_added is triggered once for each existing child and then again every time a new child is added to the specified path
所以我想把注意力集中在我真正需要的东西上,我已经做到了:
rootRef.orderByKey().startAt("-WhatTF123456789")...
但是后来我失去了我的 CRUD 功能,因为它正在监听新条目而不是所有条目。
所以我想到了一个解决方案。保留一个节点包含对 FireBase 数据库所做的所有更改,一个节点包含所有已读取本地数据库并对本地数据库进行更改的用户,以了解谁需要更新,然后使用 addChildEventListener 来这个特定的节点。但这似乎是多余的。
我有什么选择来处理这种情况?
最佳答案
The
onChildAddedlistener gets called enormous amounts of times for every child on this root.
正如您已经提到的和文档所述,这是预期的行为。通常,不建议在包含大量数据的节点(根节点)上附加 ChildEventListener。请注意这种做法,因为在下载大量数据时,您可能会遇到类似以下的错误:OutOfMemoryError .发生这种情况是因为您隐式下载了正在监听的整个节点及其下的所有数据。该数据可能以简单属性或复杂对象的形式存在。所以它可以被认为是资源和带宽的浪费。在这种情况下,最好的方法是尽可能扁平化数据库。如果您不熟悉 NoSQL 数据库,这种做法称为非规范化,是 Firebase 的常见做法。为了更好地理解,我建议您看一下:
另请注意,在复制数据时,需要牢记一件事。以与添加数据相同的方式,您需要维护它。换句话说,如果你想更新/删除一个项目,你需要在它存在的每个地方进行。
我还建议您从以下帖子中查看我答案的最后一部分:
它适用于 Cloud Firestore,但同样的规则适用于 Firebase 实时数据库。
But then I have lost my CRUD capabilities because it's listening to the new entries and not all of them.
Firebase 中的一切都与听众有关。您无法获得节点内对象的实时更新,除非您正在收听它们。所以你不能限制结果并期望从你没有收听的对象中获得更新。如果您需要获取节点内所有对象的更新,则需要监听所有这些对象。因为这种方法根本不实用,所以您可以使用上面解释的非规范化,或者通过使用可以帮助您限制从数据库中获取的数据量的查询来限制结果。关于您的解决方案,第二种更受欢迎,但您也可以考虑另一种方法,即根据 timestamp 属性或根据任何您需要的其他属性(property)。
编辑:根据您的评论:
Can you please provide tests for each solution (1.denormalization, 2.my solution) examine use of bandwidth and resources and which one is really preferred?
所有数据都经过建模以支持应用所需的用例。不幸的是,我无法进行测试,因为它实际上取决于应用程序的用例及其包含的数据量。这意味着适用于一个应用程序的内容可能不适用于另一个应用程序。所以测试可能不对每个人都是正确的。非规范化过程或您的解决方案完全取决于您打算如何查询数据库。在上面的列表中,我添加了一个新资源,这是我对 denormalization tehnique in NoSQL databases 的回答。 .希望它也能帮助介绍访问者。
关于java - Android Firebase 如何处理实时服务器到本地数据库的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54169121/
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru
我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除