当类不完全相同时,Android Java Firebase runTransaction会删除值

当类不完全相同时,Android Java Firebase runTransaction会删除值,java,android,firebase,firebase-realtime-database,transactions,Java,Android,Firebase,Firebase Realtime Database,Transactions,我在运行runTransaction func更新值时遇到了这个问题,当类不同时,这个func会从类中删除值 让我试着解释一下 这是关于我的userModel类的 应用程序版本1.0具有以下属性的用户模型 -用户名 -液体 -追随者 应用程序版本1.1具有以下属性的用户模型 -用户名 -液体 -追随者 状态(已添加) 因此,userModel还有一个附加属性 当使用appVersion 1.0的用户现在在使用appVersion 1.1的用户上运行事务时(例如,在以下情况下,我将追随者增加1

我在运行runTransaction func更新值时遇到了这个问题,当类不同时,这个func会从类中删除值 让我试着解释一下

这是关于我的userModel类的 应用程序版本1.0具有以下属性的用户模型

-用户名 -液体 -追随者

应用程序版本1.1具有以下属性的用户模型 -用户名 -液体 -追随者

  • 状态(已添加)
因此,userModel还有一个附加属性

当使用appVersion 1.0的用户现在在使用appVersion 1.1的用户上运行事务时(例如,在以下情况下,我将追随者增加1),用户1.0完成的事务仅设置其当前版本中的值,因此删除版本为1.1的用户的状态

我的代码

API.ref.databaseSpecificUser(id).runTransaction(new Transaction.Handler() {
        @Override
        public Transaction.Result doTransaction(final MutableData mutableData) {
            final User user = mutableData.getValue(User);

            if (user== null) {
                return Transaction.success(mutableData);
            }

            .....

            mutableData.setValue(user);
            return Transaction.success(mutableData);
        }

更新值但不设置状态,因为应用程序版本1.0在userModel类中不包含“状态”


有什么想法吗?

事务必须为运行它的位置提供完整的新值。您不能在
API.ref.databaseSpecificUser(id)
上运行事务,然后只为其下的单个属性提供值

在您的场景中有几个选项:

  • 不要使用(不完整的)
    User
    类调用
    setValue()
    ,而只直接更新
    mutableData
    上的特定属性。这类似于
    mutableData.child(“count”).setValue(42)
    。这样,
    mutableData
    仍将包含所有属性,即使
    User
    类不包含这些属性

  • 直接在要修改的属性上运行事务,因此:
    API.ref.databaseSpecificUser(id).child(“count”).runTransaction(…
    。这样,
    mutableData
    将只用于您正在修改的属性,因此不会删除任何其他内容。在这里,您也不会使用
    User
    类,因为您正在读/写单个属性

  • 使用较新的
    ServerValue.increment(1)
    操作来增加计数。此操作效率更高,通常会生成更简单的代码。类似于:
    ServerValue.increment(1).child(“count”).setValue(ServerValue.increment(1));


  • 这种行为听起来和我预期的一样:数据库不知道你的应用程序的版本,因此当你的事务在该位置设置数据时,它只执行该指令并写入数据。你希望它做什么?如果我们能看到为事务提供实际数据的代码,这也会很有帮助,因为它可能会让我们想出另一种方法来完成您想要的。我只想更新必要的数据,而不是此引用下的全部数据。奇怪的是,如果对我的iOS版本执行相同的操作,提供相同的代码,它不会删除任何数据。这在当前非常糟糕,因为我可能会在稍后向userModel b添加更多属性ut较旧版本的用户将删除它们…事务将在该位置设置整个值,因此该方法被称为
    setValue
    。该方法应适用于所有平台。如果要执行部分更新,则只需调用
    updateChildren
    传递需要修改的子级。如果只想更新对于单个属性,我建议只在该节点/属性上运行事务,而不是在整个用户上运行事务。如果您只想增加一个值,我建议使用
    ServerValue.increment(1)
    -这是今年早些时候添加到API中的。我正在使用runTransaction,正如firebase在递增值时建议的那样。但是,正如我正确理解的那样,如果我使用事务,就不可能只更新更改的值,对吗?谢谢你的帮助!非常感谢,我甚至不知道这个新函数!我将尝试M根据这一点改进我的代码。还有一个/最后一个问题:ServerValue.increment func将如何改变我的数据消耗?它是否比我使用runTransaction方法时要少?所以我只是用我的runTransaction func再次测试了它。runTransaction func:我的android方法正在删除未知值,而我的iOS应用程序没有,但做的完全相同。我想我知道w为什么它们的行为不同。在我的iOS版本中,我获取可变数据并选择特定值来更改它们。最后,我将该值设置为新值。在我的android版本中,我获取Post.class,因此忽略不存在的值。保存它将导致删除该类未知的值!感谢您的回复,我找到了解决方案关于我的问题!很高兴听到你找到了答案。我试图在我的回答中的选项1和选项2中解释
    User
    类导致了你的问题。如果你只需要增加一个值,那么
    ServerValue.increment()
    
    mutableData.setValue(user);