Continue insert new data in existing array in Firebase Database from Android

故事扮演 提交于 2021-01-29 11:08:47

问题


I'm just starting to learn android studio and I'm working on a location-based project to insert location information into Firebase. I followed tutorial from youtube [https://www.youtube.com/watch?v=CwxdfamaCrk], however in the video only shows insert data from the code which is like this;

infectedArea = new ArrayList<>();
    infectedArea.add(new LatLng(2.2258162, 102.4497224));
    infectedArea.add(new LatLng(2.2252313, 102.4563797));
    infectedArea.add(new LatLng(2.2261818, 102.4551067));
    infectedArea.add(new LatLng(2.275295,102.444035));

    FirebaseDatabase.getInstance()
            .getReference("InfectedArea")
            .child("Location")
            .setValue(infectedArea)
            .addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    Toast.makeText(MapsActivity.this, "Updated!", Toast.LENGTH_SHORT).show();
                }
            }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Toast.makeText(MapsActivity.this, ""+e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });

Below are the snapshot of my firebase.

The one with index 0, 1, 2 and 3 are inserted from the code. Now I'm trying to continue inserting data from an input form but random key was generated and new geofence cannot be created. Is there anyway to continue inserting data with hard key?

I was thinking on removing the hard key and just use the generated key but then I have no idea how to alter the code to create multiple geofence.


回答1:


it will stockpile at HashMap, so you can getkey to get random key, and you get random key you can insert data

DatabaseReference database = FirebaseDatabase.getInstance().getReference("InfectedArea").child("Location");
    database_course.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

            for(DataSnapshot ds :dataSnapshot.getChildren()){
               String key = ds.getKey();
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });



回答2:


Firebase intentionally doesn't offer an operation for inserting items with a sequential numeric key. See:

  • the documentation on structuring data
  • The classic blog post on best practices when using arrays in Firebase
  • How to create auto incremented key in Firebase?

That said, you can use array-like structures with sequential numerical indexes, and you can use auto-ids. So let's look at each in turn.


Using sequential numerical indexes

To add a new item with key 4 to your current structure, you will need to:

  1. Determine the highest key
  2. Add a child node with one key higher

In its simplest format, that looks like this (on Android):

FirebaseDatabase.getInstance()
        .getReference("InfectedArea")
        .child("Location")
        .runTransaction(new Transaction.Handler() {
    @Override
    public Transaction.Result doTransaction(MutableData mutableData) {
        String lastKey = "-1";
        for (MutableData child: mutableData.getChildren) {
            lastKey = child.getKey();
        }

        int nextKey = Integer.parseInt(lastKey) + 1;

        mutableData.child("" + nextKey).setValue("your next value here");

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

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

As you can see that is quite a lot of code. This is largely needed because multiple users may be accessing the same location at almost the same time, and we need to handle this. Firebase uses optimistic locking, but the above may still be come a serious bottleneck when there are multiple users. Plus: this is a lot more complex than your simple push().setValue(...).


Use auto-ids for your initial set of data, and for new data

You can easily write all points with push IDs (those are the keys that push() generates), once you realize that calling only push() doesn't yet write to the database. You can get a new push ID in pure Android code with:

String pushID = ref.push().getKey();

Knowing this, we can change your code to insert the initial locations to:

DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
// It doesn't matter what the reference points to, as push IDs are statistically guaranteed to be unique, independent of their location.

Map<String, Object> values = new HashMap<>();
infectedArea.put(ref.push().getKey(), new LatLng(2.2258162, 102.4497224));
infectedArea.put(ref.push().getKey(), new LatLng(2.2252313, 102.4563797));
infectedArea.put(ref.push().getKey(), new LatLng(2.2261818, 102.4551067));
infectedArea.put(ref.push().getKey(), new LatLng(2.275295,102.444035));

FirebaseDatabase.getInstance()
        .getReference("InfectedArea")
        .child("Location")
        .setValue(values)
        .addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                Toast.makeText(MapsActivity.this, "Updated!", Toast.LENGTH_SHORT).show();
            }
        }).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        Toast.makeText(MapsActivity.this, ""+e.getMessage(), Toast.LENGTH_SHORT).show();
    }
});

This will result in a similar structure as you know have, but then with all keys being push IDs.



来源:https://stackoverflow.com/questions/59313556/continue-insert-new-data-in-existing-array-in-firebase-database-from-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!