#android #firebase #firebase-realtime-database
#Android #firebase #firebase-база данных в реальном времени
Вопрос:
Я пытаюсь перенести созданное мной приложение, которое использовало Parse в качестве облачного сервера. В моей серверной базе данных Parse у меня была таблица, в которой хранились данные, как показано ниже:
Device ID | Contacts
xxxxx001 | "(800)-888-8888"
xxxxx002 | "(800)-888-8858"
xxxxx003 | "(800)-888-8868"
Здесь идентификатор устройства — это идентификатор устройства Android, а контакты — это список строк, который был сгенерирован с помощью логики на устройстве. По сути, пользователь выбирает контакт (несколько в будущих итерациях, следовательно, это ArrayList, для тестирования я просто сохраняю один элемент в списке), и этот контакт сохраняется для этого DeviceID в серверной базе данных. Если тот же идентификатор устройства изменяет контакт, список контактов в базе данных, соответствующий его идентификатору устройства, будет заменен новым списком ArrayList.
Я пытаюсь настроить что-то подобное на Firebase, однако сейчас кажется, что у меня есть только глобальная переменная в моей базе данных, которая, похоже, обновляется каждый раз, когда я нажимаю свою кнопку.
Вот мой код для кнопки:
DatabaseReference mRootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference mContactsRef = mRootRef.child("contacts");
@Override
protected void onStart() {
super.onStart();
mButtonContactSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mContactsRef.setValue(contacts); //contacts is an arraylist with 1 item
}
});
}
Вот как это выглядит в Firebase после нажатия кнопки 3 раза:
Вместо обновления значения, it seems to add another row(?) of to store the current phone number selected
. Как я могу настроить вид DeviceID-> (Объекты, которые будут храниться на устройстве)?
Ответ №1:
Вы ищете push()
, который генерирует уникальный идентификатор для новых элементов.
Из документации Firebase по чтению и записи списков данных:
// Create a new post reference with an auto-generated id
var newPostRef = postListRef.push();
newPostRef.set({
// ...
});
Новые элементы будут иметь сложные на вид ключи вида -KTTHEScy82fpfNSCoYN
. Прочитайте эту статью о том, почему они предпочтительнее индексов массива, и (если вам интересно) эту статью, в которой объясняется формат этих ключей.
Рассмотрим другую модель данных
В общем, хотя вы можете рассмотреть другую модель данных. То, что вы сохраняете, — это набор телефонных номеров. На первый взгляд, сохранение их в виде списка, подобного массиву, кажется прекрасным.
Но обычно вам нужно такое поведение для этого списка контактов:
- каждый номер телефона может присутствовать только один раз
- вам нужно выяснить, есть ли данный номер телефона уже в списке
С вашей текущей структурой вы можете увидеть, только если число уже есть в списке, сканируя все элементы в списке. Всякий раз, когда это так, самое время подумать об использовании заданной структуры данных.
В Firebase вы бы смоделировали набор телефонных номеров следующим образом:
"contacts": {
"(800)-888-8858": true
"(800)-888-8868": true
"(800)-888-8888": true
}
Хотя эта структура изначально выглядит менее эффективной, на самом деле она хранится более эффективно, чем список массивов в Firebase. И поиск того, существует ли элемент, теперь является простой проверкой существования вместо сканирования массива. И с такой структурой невозможно сохранить один и тот же номер дважды.
Комментарии:
1. Спасибо за ответ! Итак, в моем клиентском приложении, как мне изменить структуру данных в соответствии с моделью, которую предпочитает Firebase? Или вы имеете в виду, что я должен хранить его в HashSet? Кроме того, как бы я мог использовать метод push (), чтобы убедиться, что я сохраняю данные в идентификаторе устройства? Как человек, привыкший к реляционным базам данных, у меня возникли небольшие проблемы с системой хранения JSON, которую использует Firebase, и отсутствием надлежащих таблиц.