Добавление элемента в список в базе данных Firebase
у меня есть следующая структура базы данных военнослужащих. uIds
тип List<String>
. Я пытаюсь добавить еще один uId под uIds
с увеличенным индексом. setValue()
и updateChildren()
потребуется, чтобы я извлек существующие данные, и push()
добавит элемент со случайно сгенерированной строкой в качестве ключа вместо увеличенного индекса. Есть ли более простой способ, который не требует извлечения существующих данных? Спасибо!
"requests" : {
"request001" : {
"interests" : [ "x" ],
"live" : true,
"uIds" : [ "user1" ] // <---- from this
},
"request002" : {
"interests" : [ "y" ],
"live" : true,
"uIds" : [ "user2" ]
}
}
--------------------------------
Edit:
извините за нечеткость. Позвольте мне пояснить. Скажем, у меня есть вышеуказанная база данных и я хочу обновить ее до следующего.
"requests" : {
"-KSVYZwUQPfyosiyRVdr" : {
"interests" : [ "x" ],
"live" : true,
"uIds" : [ "user1", "user2" ] // <--- to this
},
"-KSl1L60g0tW5voyv0VU" : {
"interests" : [ "y" ],
"live" : true,
"uIds" : [ "user2" ]
}
}
предложение ишмаэльмакитлы,mDatabase.child("requests").child("request001").setValue(newRequest)
, перезапишет " request001 "с"newRequest". Поэтому я должен получить существующие данные " request001 "и добавить" user2 " в список uIds
. Это будет что-то вроде это:
mDatabase.child("requests").child("request001").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Request newRequest = dataSnapshot.getValue(Request.class);
newRequest.uIds.add("user2");
mDatabase.child("requests").child("request001").setValue(newRequest);
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
но мне интересно, нужен ли этот процесс, так как я пытаюсь просто добавить один элемент в список uIds
.
4 ответов
на Firebase документация по созданию данных, которые масштабируются предлагает использовать другую структуру данных:
"requests" : {
"-KSVYZwUQPfyosiyRVdr" : {
"interests" : { "x": true },
"live" : true,
"uIds" : {
"user1": true,
"user2": true
}
},
"-KSl1L60g0tW5voyv0VU" : {
"interests" : { "y": true },
"live" : true,
"uIds" : {
"user2": true
}
}
}
вот несколько причин, почему эта структура данных работает лучше:
- каждый uid теперь может автоматически отображаться только один раз. Мы по существу смоделировали наши данные как set, вместо использования массива.
- добавление элемента теперь так же просто, как
ref.child("uUids").child("user3").setValue(true)
- теперь вы можете проверить, если uid существует в ваших правилах безопасности.
Я начал повторять про себя: всякий раз, когда вы обнаружите, что делаете array.contains("xyz")
, вы, вероятно, должны использовать набор вместо массива. приведенное выше сопоставление с "key": true
является реализацией набора на Firebase.
эффективность
некоторые люди могут думать, что массивы являются более эффективным способом хранения данных, но в случае Firebase это не так:
что вы см.:
"uIds" : [ "user1", "user2" ]
какие магазины Firebase:
"uIds" : {
"0": "user1",
"1": "user2"
}
так хранить набор почти такой же:
"uIds" : {
"user1": true,
"user2": true
}
не уверен, что вы имеете в виду, когда говорите setValue, и т. д. требуется получить существующие данные. Основной поток для вставки новой записи выглядит следующим образом:
private DatabaseReference mDatabase;
// get reference to your Firebase Database.
mDatabase = FirebaseDatabase.getInstance().getReference();
//and here you add a new child to your 'requests' collection
//I am assuming you have a Request model like this..
Request newRequest = new Request(some-params);
mDatabase.child("requests").child(someRequestId).setValue(newRequest);
вы можете взглянуть на основных инструкция по эксплуатации сохранение данных на Android Firebase.
обновление:
После вашего комментария-я думаю, что то, что вы хотите сделать, может быть достигнуто следующим образом:
Вы используете push()
метод, который генерирует уникальный идентификатор каждый раз, когда новый ребенок добавляется указанная ссылка Firebase:
Firebase newRequestRef = mDatabase.child("request").push();
newRequestRef.setValue(newRequest);
это должно помочь.
надеюсь, это поможет.
добавление 2 центов Франк ван Puffelen ответ, вы можете использовать ключ от принудительной отправки в качестве уникального идентификатора запроса. Кроме того, если вы используете хэш-карту для обновления ребенка, ваша БД не будет переопределена
// Create a node on Server and get key
String requestID = AdminController.getInstance().referenceFromUrl
.child(END_POINT_REQUESTS)
.push().getKey();
//use key as ID for your Object which you want to push as unique identifier of your model
requestToPush.setRequestId(requestID );
//Add updated Model Object in a Map to update DB instead of over writing
requestsMap.put(requestID , requestToPush);
//Update newly created DB nodes with data
referenceFromUrl
.child(END_POINT_REQUESTS)
.updateChildren(productsMap,
new DatabaseReference.CompletionListener() {
@Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if (databaseError != null) {
Log.e(TAG, "Error: Data could not be saved "
+ databaseError.getMessage());
} else {
Log.e(TAG, "Success : Data saved successfully.");
}
}
});
результат
есть старая добрая статья из официального блога Firebase, объясняющая, почему мы должны избегать массива в нашей базе данных:массивы-зло
таким образом, невозможно изменить массив без замены массива. Я предлагаю изменить структуру вашей базы данных на this
"requests" : {
"<pushKey1>" : {
"interests" : [ "x" ],
"live" : true,
"uIds" : {
"<pushKey1>" : "user1",
"<pushKey2>" : "user2"
}
},
"<pushKey2>" : {
"interests" : [ "y" ],
"live" : true,
"uIds" : {
"<pushKey1>" : "user2"
}
}
}
для получения pushKey
, вы можете использовать push () метод (то же самое, что вы сделали с каждым Request
номенклатура)
тогда код будет таким, если вы просто хочу добавить новый uid в запрос.
String requestKey = "request001";
mDatabase.child("requests").child(requestKey).child("uIds").push().setValue("user2");
комментарий здесь, Если у вас есть вопросы, надеюсь, что это помогает :)