Как полностью удалить значение из базы данных Firebase Realtime? - PullRequest
0 голосов
/ 18 февраля 2019

Я создал массив в базе данных.Через код приложения я получаю значение из массива и хочу удалить его, но чтобы код работал, я хочу, чтобы значение было полностью удалено, то есть массив должен начинаться снова с «0», но с помощьюкоманды removeValue () он просто присваивает ноль.Как я могу удалить значение из базы данных?

Я пробовал оба removeValue и setValue (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 = 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: поиск E / IAudioFlinger: createRecord вернул ошибку -12

2019-02-20 02: 11: 25.269 2651-11949 / com.google.android.googlequicksearchbox: поиск 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: поиск E / android.media.AudioRecord: код ошибки -20 при инициализации собственного объекта AudioRecord.

2019-02-20 02: 11: 25.274 2651-11949 / com.google.android.googlequicksearchbox: поиск 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.audio.recorded

Run:

E / AndroidRuntime: FATAL EXCEPTION: main Процесс: com.example.ru.puddig, PID: 12504 com.google.firebase.database.DatabaseException: Не удалось преобразовать значение типа java.util.HashMap в строку в 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) на ком.google.firebase.database.Query $ 1.onDataChange (ком.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 @@ 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 голосов
/ 18 февраля 2019

Как объясняет статья, на которую ссылается Jainam, чтобы удалить элемент из начала массива, вам нужно загрузить весь массив, удалить клиентскую часть элемента и записать весь массив обратно.В коде это будет примерно так:

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
    }
});

Как вы видите, это довольно сложно.Причина этого заключается в том, что в массиве ключ / индекс каждого (но последнего) элемента зависит от других элементов в нем.Таким образом, удаление одного (но последнего) элемента из массива означает, что многие другие элементы необходимо обновить / переместить.По этой причине вы должны использовать массив только в том случае, если ваши данные действительно нуждаются в массиве, что означает: если одно и то же значение может встречаться в коллекции несколько раз, если необходимо поддерживать порядок значений в коллекции, и если это важно для вашегоПриложение, что ключи являются последовательными / числовыми.

Если это третье условие не применяется, я настоятельно рекомендую использовать встроенные push-идентификаторы Firebase для ключей.Это то, что описывает пост в блоге, который описывает Jainam.

Если, однако, ваши значения должны быть уникальными в коллекции, а порядок не важен, вам лучше использовать подобную множеству структуру данных.В базе данных Firebase Realtime это будет выглядеть следующим образом:

{
    "del1": true,
    "del2": true,
    "del3": true
}

Значение true здесь не важно, а просто там, поскольку Firebase не может хранить ключ без значения.Важно то, что теперь у нас есть коллекция с тремя ключами, которые гарантированно уникальны, и которые можно добавлять / удалять атомарно, без необходимости знать другие ключи.

Если у вас есть DatabaseReference к приведенной выше структуре, вы можете удалить "del1" из нее с помощью этого гораздо более простого кода:

ref.child("del1").removeValue();

Подробнее об этой структуре также см. в моем ответе здесь: Запрос Firebase, если child of childсодержит значение

0 голосов
/ 18 февраля 2019

Пожалуйста, проверьте этот блог Firebase , где они упоминают, как использовать массивы с Firebase.Подводя итог вашему вопросу, воспользуйтесь следующим пунктом в блоге.

  • для удаления ключей, мы сохраняем весь массив вместо использования .remove ()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...