从Android继续在Firebase数据库的现有阵列中插入新数据 [英] Continue insert new data in existing array in Firebase Database from Android

查看:69
本文介绍了从Android继续在Firebase数据库的现有阵列中插入新数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始学习android studio,并且我正在基于位置的项目中将位置信息插入Firebase.我遵循了youtube上的教程[

从代码中插入索引为0、1、2和3的那个.现在,我试图继续从输入表单中插入数据,但是生成了随机密钥,并且无法创建新的地理围栏.反正有继续用硬键插入数据吗?

我当时想删除硬键,只使用生成的键,但是后来我不知道如何更改代码以创建多个地理围栏.

解决方案

Firebase故意不提供使用顺序数字键插入项目的操作.参见:

也就是说,您可以使用具有顺序数字索引的类似数组的结构,并且可以使用自动标识.因此,让我们依次看一下.


使用顺序数字索引

要将键为 4 的新项目添加到当前结构中,您需要:

  1. 确定最高键
  2. 添加一个高一键的子节点

在最简单的格式下,它看起来像这样(在Android上):

  FirebaseDatabase.getInstance().getReference("InfectedArea").child(位置").runTransaction(new Transaction.Handler(){@Overridepublic Transaction.Result doTransaction(MutableData mutableData){字符串lastKey ="-1";for(MutableData child:mutableData.getChildren){lastKey = child.getKey();}int nextKey = Integer.parseInt(lastKey)+1;mutableData.child(" + nextKey).setValue(此处的下一个值");//设置价值并报告交易成功返回Transaction.success(mutableData);}@Override公共无效onComplete(DatabaseError databaseError,boolean b,DataSnapshot dataSnapshot){//交易完成Log.d(TAG,"Transaction:onComplete:" + databaseError);}}); 

如您所见,这是很多代码.这是非常需要的,因为多个用户几乎可以同时访问同一位置,因此我们需要进行处理.Firebase使用乐观锁定,但是当有多个用户时,以上可能仍然会成为严重的瓶颈.另外:这比简单的 push().setValue(...)复杂得多.


将自动编号用于您的初始数据集和新数据

一旦意识到只调用 push()不会,就可以轻松地编写带有推送ID的所有点(这些点是 push()生成的键).尚未写入数据库.您可以使用以下纯Android代码获取新的推送ID:

 字符串pushID = ref.push().getKey(); 

知道了这一点,我们可以更改您的代码以将初始位置插入到:

  DatabaseReference ref = FirebaseDatabase.getInstance().getReference();//引用指向什么都没有关系,因为从统计角度上保证推入ID的唯一性,而与它们的位置无关.Map< String,Object>值=新的HashMap<>();被感染的区域.put(ref.push().getKey(),new LatLng(2.2258162,102.4497224));被感染的区域.put(ref.push().getKey(),new LatLng(2.2252313,102.4563797));被感染的区域.put(ref.push().getKey(),new LatLng(2.2261818,102.4551067));被感染的区域.put(ref.push().getKey(),new LatLng(2.275295,102.444035));FirebaseDatabase.getInstance().getReference("InfectedArea").child(位置").setValue(值).addOnCompleteListener(new OnCompleteListener< Void>(){@Overridepublic void onComplete(@NonNull Task< Void>任务){Toast.makeText(MapsActivity.this,"Updated!",Toast.LENGTH_SHORT).show();}}).addOnFailureListener(new OnFailureListener(){@Override公共无效onFailure(@NonNull异常e){Toast.makeText(MapsActivity.this," + e.getMessage(),Toast.LENGTH_SHORT).show();}}); 

这将产生与您所知道的类似的结构,但是所有键都是推送ID.

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.

解决方案

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

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.

这篇关于从Android继续在Firebase数据库的现有阵列中插入新数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆