【问题标题】:Update other nodes when the transaction is completed交易完成时更新其他节点
【发布时间】:2018-01-30 15:50:25
【问题描述】:

我正在学习 Android 中的 Firebase,我正在尝试使用它们各自的插槽制作一个房间系统。在这种情况下,多个用户可能希望同时访问同一个插槽,因此我决定使用 Firebase 事务。

所以当用户尝试登录我的插槽时:

mySlotRef1.runTransaction(new Transaction.Handler() {
                    @Override
                    public Transaction.Result doTransaction(MutableData mutableData) {
                        Slot p = mutableData.getValue(Slot.class);
                        if (p == null) {
                            return Transaction.success(mutableData);
                        }
                        if (p.getState().equals("closed")) {
                            return Transaction.abort();
                        }

                        // Set value and report transaction success
                        Slot sl1 = new Slot("slot1", idRoom, auth.getCurrentUser().getDisplayName(), auth.getCurrentUser().getUid(), "closed", Profile.getCurrentProfile().getProfilePictureUri(200, 200).toString());
                        mutableData.setValue(sl1);
                        return Transaction.success(mutableData);
                    }

                    @Override
                    public void onComplete(DatabaseError databaseError, boolean b,
                                           DataSnapshot dataSnapshot) {
                        // Transaction completed
                        Log.d(TAG, "postTransaction:onComplete:" + databaseError);

                    }
                });

我认为这行得通,我。 e.当插槽关闭时,它只进入一个用户并拒绝“插槽”参考中的其他用户。但是问题是我还需要更新“用户”目录中的另外两个值,我找不到“仅当用户占用插槽时”的方法,即,交易完成的时间。

更新: 这是我检查插槽是否打开的部分。

mySlotRef1.addListenerForSingleValueEvent(new ValueEventListener() {

                                @Override
                                public void onDataChange(DataSnapshot dataSnapshot) {
                                    Slot data = dataSnapshot.getValue(Slot.class);
                                    state = data.getState();
                                    if (state.equals("open")) {
                                        saveSlot(slot);
                                    } else {
                                        Toast.makeText(getApplicationContext(), "Slot not available", Toast.LENGTH_SHORT).show();
                                    }
                                }

                                @Override
                                public void onCancelled(DatabaseError databaseError) {

                                }

                            });

【问题讨论】:

    标签: android firebase firebase-realtime-database


    【解决方案1】:

    这不是并发写入的工作方式。您的任何插槽都不会关闭。当您使用事务时,这意味着不同用户在同一时间进行的每次写入都将在不同的执行线程中进行。所以使用事务,不管是两个或多个其他用户同时进行写操作,你都会得到正确的结果。

    如果您想更新另一个类中的其他字段,只需将您的逻辑放在onComplete() 方法中。交易完成后触发此方法。

    【讨论】:

    • 我在 onComplete() 中做了这个:Map updates = new HashMap(); updates.put("/Users/" + auth.getCurrentUser().getUid() + "/state", "on"); updates.put("/Users/" + auth.getCurrentUser().getUid() + "/idroom", idRoom); myRef1.updateChildren(更新);
    • 但是当试图用两个用户占用槽时,它对他们都执行更新。我的意思是,两个用户都喜欢用“idroom”“打开”
    • 没错,因为每个用户都使用一个单独的事务,这意味着为每个用户调用onComplete() 方法。这就是交易的运作方式。但是你想实现什么?
    • 我想实现在所有试图占据该位置的用户中只有一个用户可以做到这一点。结果只更新了占用用户的“state”和“idroom”
    • 在这种情况下,您需要创建一个条件。您需要验证尝试访问该插槽的用户是否是您希望它能够访问的实际用户。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    相关资源
    最近更新 更多