Приращения значений в режиме реального времени - PullRequest
1 голос
/ 05 апреля 2020

В приложении может быть несколько человек, которые нажимают кнопку, которая увеличивает значение в firebase и возвращает это значение, но если каждый человек одновременно нажимает кнопку, они получат одно и то же значение, как мне это сделать? Прирост с каждым человеком, получающим различное значение?

     DatabaseReference reference = FirebaseDatabase.getInstance().getReference("queue");
    reference.child(queue_id).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            currentNum = (long) dataSnapshot.child("currentNumber").getValue();
            ++currentNum;
            dataSnapshot.child("currentNumber").getRef().setValue(++currentNum);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });

Ответы [ 3 ]

2 голосов
/ 05 апреля 2020

Чтобы предотвратить конфликты между несколькими пользователями, обновляющими один и тот же узел (почти) в одно и то же время, необходимо использовать транзакцию. В вашем случае это будет выглядеть примерно так:

DatabaseReference reference = FirebaseDatabase.getInstance().getReference("queue");
DatabaseReference numberRef = reference.child(queue_id).child("currentNumber");

numberRef.runTransaction(new Transaction.Handler() {
    @Override
    public Transaction.Result doTransaction(MutableData mutableData) {
        Long value = mutableData.getValue(Long.class);
        if (value == null) {
            mutableData.setValue(1);
        }
        else {
            mutableData.setValue(value+1);
        }
        return Transaction.success(mutableData);
    }
}

@Override
public void onComplete(DatabaseError databaseError, boolean b,
                       DataSnapshot dataSnapshot) {
    // Transaction completed
    Log.d(TAG, "runTransaction:onComplete:" + databaseError);
}
0 голосов
/ 05 апреля 2020

Вы можете использовать метод transactions. Ссылка на эту ссылку: https://firebase.google.com/docs/database/android/read-and-write#save_data_as_transactions "

private void onStarClicked(DatabaseReference postRef) {
    postRef.runTransaction(new Transaction.Handler() {
        @Override
        public Transaction.Result doTransaction(MutableData mutableData) {
            Post p = mutableData.getValue(Post.class);
            if (p == null) {
                return Transaction.success(mutableData);
            }
        if (p.stars.containsKey(getUid())) {
            // Unstar the post and remove self from stars
            p.starCount = p.starCount - 1;
            p.stars.remove(getUid());
        } else {
            // Star the post and add self to stars
            p.starCount = p.starCount + 1;
            p.stars.put(getUid(), true);
        }

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

    @Override
    public void onComplete(DatabaseError databaseError, boolean b,
                           DataSnapshot dataSnapshot) {
        // Transaction completed
        Log.d(TAG, "postTransaction:onComplete:" + databaseError);
    }
});
}
0 голосов
/ 05 апреля 2020

Согласно вашему коду, вы увеличиваете счетчик на 1, но не публикуете его в базе данных. Используйте HashMap для обновления данных в вашей базе данных при ее изменении. Вы можете попробовать следующий код:

    button.setOnClickListerner(new View.onClickListener() {
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference("queue");
    reference.child(queue_id).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            currentNum = (long) dataSnapshot.child("currentNumber").getValue();
            long newValue = currentNum + 1;
            HasMap<String, Object> hashMap = new HashMap<>();
            hashMap.put ("currentNumber", newValue);
            reference.child(queue_id).updateChildren(hashMap);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });
};

Надеюсь, это работает!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...