如何从Firebase实时数据库中完全删除值?

时间:2019-02-18 11:10:03

标签: android firebase firebase-realtime-database

我在数据库中创建了一个数组。通过应用程序的代码,我从数组中获取了值,并希望将其删除,但是要使代码正常工作,我希望将值完全删除,即,数组必须再次以“ 0”开头,但需要帮助在removeValue()命令中,它只是分配一个null。如何从数据库中删除值?

我同时尝试了removeValuesetValue (null),但是它仍然将null中的值替换为基数。

import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.util.Map;

public class MainActivity extends AppCompatActivity {

    Button mButtonSee;
    TextView mTextViewPromo;

    DatabaseReference mRef = FirebaseDatabase.getInstance().getReference();
    DatabaseReference mPromoRef =                 
mRef.child("delivery").child("0").child("promokod");

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mButtonSee = findViewById(R.id.buttonSee);
        mTextViewPromo = findViewById(R.id.promo);

        mButtonSee.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                mPromoRef.addListenerForSingleValueEvent(new 
ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    String text = dataSnapshot.getValue(String.class);
                    mTextViewPromo.setText(text);
                    mPromoRef.removeValue();
                }

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

                    }

                });

            }
        });

    }
}

因此,当我单击按钮时,我想从第一个数组中获取一个值,然后将其删除,然后再次从新的第一个数组中获取该值。

这是数据库结构:

enter image description here

我的新代码:

public class MainActivity extends AppCompatActivity {


Button mButtonSee;
TextView mTextViewPromo;


DatabaseReference mRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference mPromoRef = mRef.child("delivery");


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    mButtonSee = findViewById(R.id.buttonSee);
    mTextViewPromo = findViewById(R.id.promo);


    mButtonSee.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            mPromoRef.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    LinkedList<String> values = new LinkedList<>();
                    boolean isFirst = true;
                    for (DataSnapshot codeSnapshot: dataSnapshot.getChildren()) {
                        if (isFirst) {
                            isFirst = false;
                        }
                        else {
                            String text = codeSnapshot.getValue(String.class);
                            values.add(text);
                        }
                    }
                    mPromoRef.setValue(values);
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {
                    throw databaseError.toException();
                }

            });

        }
    });

}
}

和logcat:2019-02-20 02:11:25.263 1631-2110 /? E / AudioFlinger:内存不足,无法容纳AudioTrack size = 131296

2019-02-20 02:11:25.263 1631-2110 /? E / AudioFlinger:createRecordTrack_l()initCheck失败-12;没有控制块?

2019-02-20 02:11:25.267 1631-12210 /? I / AudioFlinger:AudioFlinger的线程0xef703a00 tid = 12210准备运行

2019-02-20 02:11:25.269 2651-11949 / com.google.android.googlequicksearchbox:search E / IAudioFlinger:createRecord返回错误-12

2019-02-20 02:11:25.269 2651-11949 / com.google.android.googlequicksearchbox:search E / AudioRecord:AudioFlinger无法创建记录轨道,状态:-12

2019-02-20 02:11:25.271 2651-11949 / com.google.android.googlequicksearchbox:search E / AudioRecord-JNI:创建AudioRecord实例时出错:初始化检查失败,状态为-12。

2019-02-20 02:11:25.274 2651-11949 / com.google.android.googlequicksearchbox:search E / android.media.AudioRecord:初始化本机AudioRecord对象时出现错误代码-20。

2019-02-20 02:11:25.274 2651-11949 / com.google.android.googlequicksearchbox:search I / MicrophoneInputStream:mic_started SR:16000 CC:16 SO:6

2019-02-20 02:11:25.275 2651-11949 / com.google.android.googlequicksearchbox:search E / ActivityThread:无法找到com.google.android.apps.gsa.testing.ui的提供商信息。录音

运行:

E / Android运行时:致命异常:主要     流程:com.example.ru.puddig,PID:12504     com.google.firebase.database.DatabaseException:无法将类型java.util.HashMap的值转换为String         在com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertString(com.google.firebase:firebase-database @@ 16.0.6:413)         com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-database @@ 16.0.6:199)         com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(com.google.firebase:firebase-database @@ 16.0.6:79)         com.google.firebase.database.DataSnapshot.getValue(com.google.firebase:firebase-database @@ 16.0.6:212)         在com.example.ru.puddig.MainActivity $ 1 $ 1.onDataChange(MainActivity.java:54)         com.google.firebase.database.Query $ 1.onDataChange(com.google.firebase:firebase-database @@ 16.0.6:183)         com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database @@ 16.0.6:75)         位于com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database @@ 16.0.6:63)         com.google.firebase.database.core.view.EventRaiser $ 1.run(com.google.firebase:firebase-database @@ 16.0.6:55)         在android.os.Handler.handleCallback(Handler.java:873)         在android.os.Handler.dispatchMessage(Handler.java:99)         在android.os.Looper.loop(Looper.java:193)         在android.app.ActivityThread.main(ActivityThread.java:6669)         在java.lang.reflect.Method.invoke(本机方法)         在com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run(RuntimeInit.java:493)         在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

2 个答案:

答案 0 :(得分:1)

请检查this firebase blog,其中提到了如何在Firebase中使用数组。总结一下您的问题,请从博客中获取以下几点。

  
      
  • 要删除键,我们将保存整个数组,而不是使用.remove()
  •   

答案 1 :(得分:1)

正如Jainam链接的文章所解释的那样,要从数组的开头删除项目,您将需要加载整个数组,删除项目客户端,然后将整个数组写回。在代码中将是这样的:

apicontext, applicationName, messageID, appKey

如您所见,这非常复杂。这样做的原因是,在数组中,每个(但最后一个)元素的键/索引都取决于其中的其他元素。因此,从数组中删除一个元素(但最后一个元素)意味着许多其他元素需要更新/移动。因此,仅当数据实际需要数组时才应使用数组,这意味着:如果同一值可以在集合中多次出现,是否必须保持集合中值的顺序,以及它是否对您至关重要?密钥为连续/数字的应用程序。

如果不符合第三个条件,我强烈建议您使用Firebase的内置按键ID作为键。这就是Jainam所指的博客文章。

但是,如果您的值在集合中必须唯一并且顺序不重要,那么最好使用类似集合的数据结构。在Firebase实时数据库中,如下所示:

DatabaseReference mRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference mPromoRef = mRef.child("delivery");
mPromoRef.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        List<String> values = new LinkedList<String>();
        boolean isFirst = true;
        for (DataSnapshot codeSnapshot: dataSnapshot.getChildren()) {
            if (isFirst) {
                isFirst = false;
            }
            else {
                String text = codeSnapshot.getValue(String.class);
                values.add(text);
            }
        }
        mPromoRef.setValue(values);
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        throw databaseError.toException(); // don't ignore errors
    }
});

此处的值{ "del1": true, "del2": true, "del3": true } 并不重要,只是在这里,因为Firebase无法存储没有值的密钥。重要的是,我们现在有一个包含三个键的集合,这些键保证是唯一的,并且可以原子地添加/删除所有这些键,而无需了解其他键。

如果您对以上结构有一个true,则可以使用以下更简单的代码从其中删除DatabaseReference

"del1"

有关此结构的更多信息,请参见此处的答案:Firebase query if child of child contains a value