1

my data look like this

enter image description here

and I simply want to add an object at index 3. How could I add it there. Is there any way to add an object without iteration or I have to iterate and getChildCount and then append new child("3") and it's data to it.

            TransGenderBO transGenderBO = new TransGenderBO();
            transGenderBO.setName("pushName");
            transGenderBO.setAge(13);

            mRef.child("").setValue(transGenderBO);

there is no method in mRef for getting child count and appending new item at 3 position..

Edit after using Frank code but still not working

            Query last = mRef.orderByKey().limitToLast(1);

            last.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    int lastIndex = 0;
                    for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
                        lastIndex = Integer.parseInt(childSnapshot.getKey());
                    }

                    TransGenderBO transGenderBO = new TransGenderBO();
                    transGenderBO.setName("pushName");
                    transGenderBO.setAge(13);
                    mRef.child(""+(lastIndex+1)).setValue(transGenderBO);
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {
                    Toast.makeText(mContext,databaseError.getMessage(),Toast.LENGTH_LONG).show();
                }
            });
1
  • In this case, you should determine next position by getting the list first. But you can use push() and will generate you a key based time. mRef.push().setValue(); Commented Aug 19, 2017 at 14:29

2 Answers 2

2

There is a good reason that the Firebase documentation and blog recommend against using arrays in the database: they don't work very well for multi-user applications where users can be offline.

To add the next element to your array here, you'll have to download at the very least the last element of the array to know the index of the next element:

Query last = root.orderByKey().limitToLast(1);
last.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        int lastIndex;
        for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
            lastIndex = Integer.parseInt(childSnapshot.getKey());
        }
        root.child(""+(lastIndex+1)).setValue(true);
    }

But this has an inherent race-condition. When multiple users are adding elements to the array at the same time, they may end up writing to the same index.

To prevent this you can use a Firebase transaction. With this you get the current value from a location and in exchange return the new value you want at that location. This ensures that no data is overwritten between users, but means that you have to download the entire array.

And neither of these scenarios works when a user is not connected to the network.

Firebase instead recommends using so-called push IDs, which:

  • Generate a always-increasing key that is guaranteed to be unique.
  • Do not require reading any data - they are generated client-side and are statistically guaranteed to be unique.
  • Also work when a user is offline.

The only disadvantage is that they're not as easily readable as array indexes.

Sign up to request clarification or add additional context in comments.

3 Comments

I like your approach but onDataChange doesn't get called.
Error creating evaluation class loader: java.lang.ClassCastException: com.sun.tools.jdi.ClassTypeImpl cannot be cast to com.sun.jdi.ArrayType
Keep in mind that Stack Overflow is no replacement a debugger. Did you step through that updated code? What line throws that exception? What's the full stack trace?
0

Get your data like this

private ArrayList<TransGenderBO> transGenderBO;
FirebaseDatabase.getInstance().getReference().child("Main")
            .addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        transGenderBO = (ArrayList<TransGenderBO>) dataSnapshot.getValue();
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});

and set your value like this

TransGenderBO transGender = new TransGenderBO();
    transGender.setName("pushName");
    transGender.setAge(13);
    FirebaseDatabase.getInstance().getReference().child("Main").child(String.valueOf(transGenderBO.size())).setValue(transGender);

or U can set this way too

TransGenderBO transGender = new TransGenderBO();
    transGender.setName("pushName");
    transGender.setAge(13);
   TransGenderBO.add(transGender);
    FirebaseDatabase.getInstance().getReference().child("Main")
  .setValue(transGenderBO);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.