mevrick
mevrick

Reputation: 1045

Insert integer if doesn't exist, increment if already exists in Firebase realtime database Android

I am trying to generate a random integer between 1 & 5 and insert the integer in Firebase database when saveData() is called first time. After the first time, when saveData() is called the integer should be incremented(new generated integer should be added to previously inserted integer). Every time saveData() is called below code over writes the previously inserted integer instead of incrementing the integer.

protected fun saveData() {
    val randomInt = Random().nextInt((5-1) + 1)//generates int between 1 & 5
    val user = User(randomInt)

    val currentUser = mAuth?.currentUser
    val uid: String = currentUser!!.uid
    val ref = FirebaseDatabase.getInstance().getReference("users").child(uid)

    ref.setValue(user).addOnCompleteListener {
        Toast.makeText(this,"Successful" , Toast.LENGTH_SHORT).show()
    }
}

User.kt

class User(val randomInt: Int)

Structure which I am getting in firebase database after saveData() is called for lets say 3 times and lets say random integers generated each time are 2, 1 and 4:

    my-firebase-app-5c40
       |__-Lhi7dewd7878dew
               |__randomInt: 4 //2 is overwritten 1 and 1 is overwritten by 4 

Whereas I want it to be:

        my-firebase-app-5c40
       |__-Lhi7dewd7878dew
               |__randomInt: 7 //2 + 1 + 4

So, in a nutshell I want to increment the value of randomInt everytime saveData() is called instead of overwriting the previous inserted value which is happening with my current code.

Upvotes: 3

Views: 888

Answers (2)

Frank van Puffelen
Frank van Puffelen

Reputation: 599571

You're looking for a Firebase Database transaction, which is the only reliable way to update a property based on its existing value in a multi-user environment. Based on the example in the documentation, your code should look something like this:

val ref = FirebaseDatabase.getInstance().getReference("users").child(uid).child("randomInt")

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

        return Transaction.success(mutableData);
    }

    @Override
    public void onComplete(DatabaseError databaseError, boolean b,
                           DataSnapshot dataSnapshot) {
        Log.d(TAG, "transaction:onComplete:" + databaseError);
    }

Upvotes: 4

ʍѳђઽ૯ท
ʍѳђઽ૯ท

Reputation: 16976

This is an integer which you’re trying to save in the database:

val randomInt: Int

Basically, the random function works properly. So, if you’re trying to save 2 + 1 + 4 in that user’s item, you probably should send the data as string and change the database item to string in order to be able to save as an string.

  • However, you’ll also need to change your random function which would return such numbers.

To do that, if you’re getting those numbers after three times, run the random function for three times and then save each value of three times running code and send it as string into the database.

Upvotes: 0

Related Questions