Consider a collection of users
. Each document in the collection has name
and email
as fields.
{
\"users\": {
\"uid1\
I wrote some routines to help automate this process back when I posted the question. I did not post them since these are a bit rudimentary and I was hoping for an elegant Firestore-based solution. Because such solution is not still available, here are the functions I wrote.
In short, we have functions for renaming a field, adding a field, or deleting a field. To rename a field, different functions are used depending on the data type. Maybe someone could generalise this better? The functions below are:
Add field:
public void add_field (final String key, final Object value, final String collection_ref) {
FirebaseFirestore.getInstance().collection(collection_ref).get()
.addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
if (task.isSuccessful()) {
WriteBatch batch = db.batch();
for (DocumentSnapshot document : task.getResult()) {
DocumentReference docRef = document.getReference();
Map new_map = new HashMap<>();
new_map.put(key, value);
batch.update(docRef, new_map);
}
batch.commit();
} else {
// ... "Error adding field -> " + task.getException()
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// ... "Failure getting documents -> " + e
}
});
}
Delete field:
public void delete_field (final String key, final String collection_ref) {
FirebaseFirestore.getInstance().collection(collection_ref).get()
.addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
if (task.isSuccessful()) {
WriteBatch batch = db.batch();
for (DocumentSnapshot document : task.getResult()) {
DocumentReference docRef = document.getReference();
Map delete_field = new HashMap<>();
delete_field.put(key, FieldValue.delete());
batch.update(docRef, delete_field);
}
// Commit the batch
batch.commit().addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
// ...
}
});
} else {
// ... "Error updating field -> " + task.getException()
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// ... "Failure getting notices -> " + e
}
});
}
Rename field:
public void rename_string_field (final String old_key, final String new_key, final String collection_ref) {
FirebaseFirestore.getInstance().collection(collection_ref).get()
.addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
if (task.isSuccessful()) {
WriteBatch batch = db.batch();
for (DocumentSnapshot document : task.getResult()) {
DocumentReference docRef = document.getReference();
String old_value = document.getString(old_key);
if (old_value != null) {
Map new_map = new HashMap<>();
new_map.put(new_key, old_value);
Map delete_old = new HashMap<>();
delete_old.put(old_key, FieldValue.delete());
batch.update(docRef, new_map);
batch.update(docRef, delete_old);
}
}
// Commit the batch
batch.commit().addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
// ...
}
});
} else {
// ... "Error updating field -> " + task.getException()
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// ... "Failure getting notices ->" + e
}
});
}
public void rename_integer_field (final String old_key, final String new_key, final String collection_ref) {
FirebaseFirestore.getInstance().collection(collection_ref).get()
.addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
if (task.isSuccessful()) {
WriteBatch batch = db.batch();
for (DocumentSnapshot document : task.getResult()) {
DocumentReference docRef = document.getReference();
int old_value = document.getDouble(old_key).intValue();
Integer ov = old_value;
if (ov != null) {
Map new_map = new HashMap<>();
new_map.put(new_key, old_value);
Map delete_old = new HashMap<>();
delete_old.put(old_key, FieldValue.delete());
batch.update(docRef, new_map);
batch.update(docRef, delete_old);
}
}
// Commit the batch
batch.commit().addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
// ...
}
});
} else {
// ... "Error updating field -> " + task.getException()
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// ... "Failure getting notices -> " + e
}
});
}
public void rename_date_field (final String old_key, final String new_key, final String collection_ref) {
FirebaseFirestore.getInstance().collection(collection_ref).get()
.addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
if (task.isSuccessful()) {
WriteBatch batch = db.batch();
for (DocumentSnapshot document : task.getResult()) {
DocumentReference docRef = document.getReference();
Date old_value = document.getDate(old_key);
if (old_value != null) {
Map new_map = new HashMap<>();
new_map.put(new_key, old_value);
Map delete_old = new HashMap<>();
delete_old.put(old_key, FieldValue.delete());
batch.update(docRef, new_map);
batch.update(docRef, delete_old);
}
}
// Commit the batch
batch.commit().addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
// ...
}
});
} else {
// ... "Error updating field -> " + task.getException()
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// ... "Failure getting notices -> " + e
}
});
}