繁体   English   中英

每当数据更改时,都会执行 if 和 else 语句

[英]Whenever the data is changed, both if and else statements are executed

我写了一个 function 来检查房间是否已满,如果是,则启动 toast,否则将播放器添加到房间。
当房间已满或有多个空闲位置时,一切正常,但当只有一个空闲位置时,if 和 else 语句都会执行。
发生这种情况是因为当玩家加入房间时数据发生了变化,我知道我必须使用 onDataChange 或 Transaction 来防止这种情况。
据我所知,我只能在直接访问数据库时使用它们,但是,我不想使用 function 直接访问数据库,而是使用我的 DAL class。

  public void joinRoom(String category, String roomID, String roomName, Context context) {
    // Checks if there is room for another player

    roomDAL.isTheRoomFull(category, roomID, roomName, (isFull) -> {
        Log.d("TAG", "isFull: " + isFull);
        if (isFull) {
            Toast.makeText(context, "The room is full", Toast.LENGTH_SHORT).show();
        }
        else{
            // run only if the user confirmed the message
            Runnable runIfConfirmed = new Runnable() {
                @Override
                public void run() {
                    // adds the player to the room
                    RoomDAL.addNewUser(category, roomID, playerDAL.getPlayerID());
                    // switches activity to GameRoom
                    SwitchActivities.GameRoom(context, roomName, category, roomID);
                    // updates the player's rooms list
                    playerDAL.addRoom(category, roomID);
                    Log.d("TAG", "Joined");
                }
            };
            // ask the user to confirm that he wants to join the room
            doubleCheck(category, roomID, roomName, runIfConfirmed);
        }
    });

    return;
}

编辑:添加访问 Firebase 的相关类。

function 检查给定房间是否已满。

    public static void isTheRoomFull(String category, String roomID, String nameRoom, OnSuccessListener<Boolean> listener) {

    DatabaseReference database = getPathReference("Rooms/" + category + "/" + roomID);
    database.addValueEventListener(new ValueEventListener() {

        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            // get the room object
            RoomDAL.getRoom(roomID, category, (room) -> {

                // Checks if the room has reached its limit
                if (room.getNumOfPlayers() == room.getCapacity()) {
                    listener.onSuccess(true);
                } else {
                    listener.onSuccess(false);
                }
            });
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
        }
    });
    return;
}

function 将给定用户添加到给定房间

  public static void addNewUser(String category, String roomID, String playerID) {

    DatabaseReference reference = getPathReference("Rooms/" + category + "/" + roomID);

    // Access the player's details in the FireStore Database
    DocumentReference docRef = fStore.collection("users").document(playerID);
    docRef.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
        @Override
        public void onSuccess(DocumentSnapshot documentSnapshot) {
            Player p = documentSnapshot.toObject(Player.class);
            String playerName = p.getFullName();

            // Add the player to the usersList
            DatabaseReference usersList = reference.child("usersList");
            HashMap<String, Object> newUser = new HashMap<>();

            newUser.put(playerID, playerName);
            usersList.updateChildren(newUser);
        }
    });

    // Increment the number of players in room
    reference.runTransaction(new Transaction.Handler() {
        @Override
        public Transaction.Result doTransaction(MutableData mutableData) {
            Room room = mutableData.getValue(Room.class);
            if (room == null) {
                return Transaction.success(mutableData);
            }

            // Update number of players
            room.setNumOfPlayers(room.getNumOfPlayers() + 1);

            // Set value and report transaction success
            mutableData.setValue(room);
            return Transaction.success(mutableData);

        }

        @Override
        public void onComplete(DatabaseError databaseError, boolean committed,
                               DataSnapshot currentData) {
            // Transaction completed
        }
    });

}

function 将给定房间添加到数据库中 userRooms 表中的用户房间列表中

    public static void addRoom(String category, String roomKey) {

    final FirebaseDatabase database = FirebaseDatabase.getInstance();
    DatabaseReference ref = database.getReference();

    DatabaseReference usersRef = ref.child("userRooms/" + getPlayerID() + "/" + category);
    Map<String, Object> groups = new HashMap<>();
    groups.put(roomKey, roomKey);

    usersRef.updateChildren(groups);
}

问题在这里:

public static void isTheRoomFull(String category, String roomID, String nameRoom, OnSuccessListener<Boolean> listener) {

    DatabaseReference database = getPathReference("Rooms/" + category + "/" + roomID);
    database.addValueEventListener(new ValueEventListener() {
        ...

由于您使用addValueEventListener注册了侦听器,因此它是一个永久侦听器,既获取当前值,然后继续侦听对该值的更改。 因此,当您随后将用户添加到房间时,将再次调用值侦听器并为(现在已满)房间触发。

最简单的解决方法是使用单事件侦听器:

database.addListenerForSingleValueEvent(new ValueEventListener() {
    ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM