Firebase data deleted when you delete different data with same key? - firebase

When I delete the first node "List" in Firebase, the second node "List 2" is automatically deleted. I think this is happening due to same key of child of both nodes. Is there any way to stop another node from being deleting?
Here's my code which I'm using to copy data from "List" to "List 2" and then delete the node "List". When I delete the one node the other also get deletd.
ref.child("List").child(cardTitle).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
ref.child("SHOP_ITEM").child("List 2).setValue(dataSnapshot.getValue());
ref.child("SHOP_ITEM").child("List").removeValue();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

I had the same problem, so I used a work around; I simply added a cancel value to it. Something like cancel:"true".
In your case DATABASEREF1 = List1 and DATABASEREF2 = List2..
This was what worked for me. Here is the code:
DATABASEREF1.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
HashMap<String,String> hMdataSnapshot = (HashMap<String, String>) dataSnapshot.getValue();
hMdataSnapshot.put("canceled","true");
DATABASEREF2.setValue(hMdataSnapshot).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
DATABASEREF1.removeValue().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
//DO SOMETHING
} else {
//DO SOMETHING
}
}
});
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
//DO SOMETHING
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

Related

How to rewrite the following code since the FirebaseInstanceId() is deprecated?

The code was found from a Youtube tutorial called realtime location firebase and it's important for my Final Year Project. I appreciate all the help that i could get. Thanks in advance.
private void updateToken(FirebaseUser firebaseUser) {
DatabaseReference tokens = FirebaseDatabase.getInstance().getReference(Common.TOKENS);
//Get Token
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
#Override
public void onSuccess(InstanceIdResult instanceIdResult) {
tokens.child(firebaseUser.getUid()).setValue(instanceIdResult.getToken());
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this, ""+e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
private void updateToken(FirebaseUser firebaseUser) {
DatabaseReference tokens = FirebaseDatabase.getInstance()
.getReference(Common.TOKENS);
FirebaseInstallations.getInstance().getId()
.addOnCompleteListener(new OnCompleteListener<String>() {
#Override
public void onComplete(#NonNull Task<String> task) {
tokens.child(firebaseUser.getUid())
.setValue(task.getResult());
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this, "" + e.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
also try some dependencies in build.gradle(:app)
implementation platform('com.google.firebase:firebase-bom:26.8.0')
implementation 'com.google.firebase:firebase-database'

how to delete a node from firebase

I am developing an android project with firebase. and now I want to delete a node on clicking on a button. but this error occurred and I can not solve it. I want to delete the node of 1589445758397. as I press the delete button all posts in the node post start deleting one by one and then the upper node with name Posts delete. please help me to solve it.
here's my code-
private void deletePostsWithImages(final String pId, String pImage) {
////////////////////////////
final ProgressDialog progressDialog = new ProgressDialog(context);
progressDialog.setTitle("Deleting Post");
progressDialog.setMessage("Please wait...");
progressDialog.show();
/////////////////////
StorageReference picRef = FirebaseStorage.getInstance().getReferenceFromUrl(pImage);
picRef.delete()
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Query fQuery = FirebaseDatabase.getInstance().getReference("Posts")
.orderByChild("pId").equalTo(pId);
fQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()) {
ds.getRef().removeValue();
Toast.makeText(context, "Post deleted successfully.", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
progressDialog.dismiss();
Toast.makeText(context, "" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
private void deletePostsWithoutImages(final String pId) {
final ProgressDialog progressDialog = new ProgressDialog(context);
progressDialog.setTitle("Deleting Post");
progressDialog.setMessage("Please wait...");
progressDialog.show();
Query fQuery = FirebaseDatabase.getInstance().getReference("Posts")
.orderByChild("pId").equalTo(pId);
fQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()) {
ds.getRef().removeValue();
Toast.makeText(context, "Post deleted successfully.", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/r7nrI.png
Instead of:
for (DataSnapshot ds: dataSnapshot.getChildren()) {
ds.getRef().removeValue();
Toast.makeText(context, "Post deleted successfully.", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
try:
dataSnapshot.setValue(null);
Toast.makeText(context, "Post deleted successfully.", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
If you want to remove some specific node and you have the ID of the node then why are you listening and looping?
Just point to the node and remove it:
private void deletePostsWithoutImages(final String pId) {
.......
.......
//point to the node
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Posts").child(pId);
//remove that node
ref.removeValue();
........
}

Retrieving images from firebase storage

I have uploaded some photos to firebase storage, and I need to connect each of those images with a document in my Cloud Firestore and then show them in my recyclerView. Do i get the url of each image, and add a field "image" to each of the documents in the firestore and use the url as a value? And then how do I put them in my RecyclerView?
I have successfully retrieved other data from the Firestore, using FirestoreUI, however I'm not sure how to do the same for images.
RecyclerViewAdapter Class
public class FirebaseRecyclerViewAdapter extends
FirestoreRecyclerAdapter<Buildings,
FirebaseRecyclerViewAdapter.FirebaseRecyclerViewHolder> {
public FirebaseRecyclerViewAdapter(FirestoreRecyclerOptions<Buildings>
options) {
super(options);
}
#Override
protected void onBindViewHolder(FirebaseRecyclerViewHolder holder, int
position, Buildings model) {
holder.textViewName.setText(model.getName());
}
#NonNull
#Override
public FirebaseRecyclerViewHolder onCreateViewHolder(#NonNull ViewGroup
parent, int viewType) {
View v =
LayoutInflater.from(parent.getContext()).inflate
(R.layout.buildings_row_item, parent, false);
return new FirebaseRecyclerViewHolder(v);
}
class FirebaseRecyclerViewHolder extends RecyclerView.ViewHolder {
TextView textViewName;
public FirebaseRecyclerViewHolder(View itemView) {
super(itemView);
textViewName = itemView.findViewById(R.id.building_name);
}
}
}
MainActivity Class
public class MainActivity extends AppCompatActivity {
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference buildingRef = db.collection("Building");
StorageReference storageReference =
FirebaseStorage.getInstance().getReference();
private FirebaseRecyclerViewAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_2);
setUpRecyclerView();
getSupportActionBar().hide();
}
private void setUpRecyclerView() {
Query query = buildingRef.orderBy("name", Query.Direction.DESCENDING);
FirestoreRecyclerOptions<Buildings> options = new
FirestoreRecyclerOptions.Builder<Buildings>()
.setQuery(query, Buildings.class)
.build();
adapter = new FirebaseRecyclerViewAdapter(options);
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
}
first of all, you need to upload the image you want to the Firestore Storage using
StorageReference
then you have to save the URL using
getDownloadUrl()
Next Step is to save the URL into field in the document and here an Example
upload the image
private void uploadFile() {
if (mImageUri != null) {
StorageReference fileReference = mStorageRef.child(System.currentTimeMillis()
+ "." + getFileExtension(mImageUri));
mUploadTask = fileReference.putFile(mImageUri)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(context, "Upload successful", Toast.LENGTH_LONG).show();
fileReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
image=new Images(mID+"",Objects.requireNonNull( uri.toString()));
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(context, "Upload Failed", Toast.LENGTH_LONG).show();
}
});
}
}
)
.addOnFailureListener(e ->
Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show())
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(context, "Uploading...", Toast.LENGTH_LONG).show();
}
});
} else {
Toast.makeText(context, "No file selected", Toast.LENGTH_SHORT).show();
}
}
save the URL to Firestore document
if(!TextUtils.isEmpty(image.getmImageUrl()))
mProperty = new Property(mID, username,mCity ,mDesc,mPrice,noRooms,noBathrooms,address,date,area,parking,Objects.requireNonNull(image.getmImageUrl()));
else
mProperty = new Property(mID, username,mCity ,mDesc,mPrice,noRooms,noBathrooms,address,date,area,parking);
db.collection("Property").document(mProperty.getmID() + "").set(mProperty)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(context, "done",
Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(context, "Failed",
Toast.LENGTH_SHORT).show();
}
});
boolean flag;
} else {
mError.setText("Empty Fields");
mError.setVisibility(View.VISIBLE);
}
i am using a model to insert data into firestore you should do that too
and in RecyclerAdapter you can bind the image to the Recyclerview using either Picasso or Bitmap
Picasso.get().load(model.getmImageDrawable()).
fit().placeholder(R.drawable.placeholder_image).
error(R.drawable.no_img).into(holder.mImage)

Retrieving list of images from Firebase, using GenericTypeIndicator<Map<String, String>>() { }

I need help with this, I've been trying to show a list of images into a recycler view but seriously I can't.
This is my database in firebase, shows the images from different events with randoms ids
This is my class:
public class Imagenes {
GenericTypeIndicator<Map<String,String>> images = new GenericTypeIndicator<Map<String, String>>(){};
public Imagenes(GenericTypeIndicator<Map<String, String>> images) {
this.images = images;
}
public GenericTypeIndicator<Map<String, String>> getImages() {
return images;
}
public void setImages(GenericTypeIndicator<Map<String, String>> images) {
this.images = images;
}
}
And yes its seems very bad but I don't know how to do it, since its not like a normal class with
name
phone
images
I mean i don't know their names, it's just random. I been reading that I have to use this kind of map, but I don't know how to use it in a class
This is my code in EventSingle:
public class EventoSingleActivity extends AppCompatActivity {
DatabaseReference mDatabaseEvento;
TextView TituloEvento;
RecyclerView mListaImagenes;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_evento_single);
mListaImagenes = (RecyclerView) findViewById(R.id.listaImagenes);
mListaImagenes.setHasFixedSize(true);
mListaImagenes.setLayoutManager(new LinearLayoutManager(this));
String Evento_key = getIntent().getExtras().getString("Evento_id");
Toast.makeText(this, Evento_key, Toast.LENGTH_SHORT).show();
mDatabaseEvento = FirebaseDatabase.getInstance().getReference().child("Evento").child(Evento_key).child("Imagenes");
System.out.println(mDatabaseEvento);
TituloEvento = (TextView) findViewById(R.id.tituloEventoField);
mDatabaseEvento.keepSynced(true);
}
#Override
protected void onStart() {
super.onStart();
FirebaseRecyclerAdapter<Imagenes, ImagenesEventoViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Imagenes, ImagenesEventoViewHolder>(
Imagenes.class,
R.layout.cardview_imagen,
ImagenesEventoViewHolder.class,
mDatabaseEvento
) {
#Override
protected void populateViewHolder(final ImagenesEventoViewHolder viewHolder, Imagenes model, int position) {
mDatabaseEvento.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println("Estoy entrando aqui");
Log.i("gguwu", "Ayudaaaa");
GenericTypeIndicator<Map<String,String>> ImagenesType = new GenericTypeIndicator<Map<String, String>>() { };
Map<String,String> Imagenes = dataSnapshot.getValue(ImagenesType);
if (Imagenes!=null ) {
for (String imagen: Imagenes.values()) {
System.out.println(imagen);
viewHolder.setImagen(getApplicationContext(), imagen);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
};
mListaImagenes.setAdapter(firebaseRecyclerAdapter);
}
public static class ImagenesEventoViewHolder extends RecyclerView.ViewHolder{
View view;
public ImagenesEventoViewHolder(View itemView) {
super(itemView);
view = itemView;
}
public void setImagen(Context ctx, String imagen){
ImageView imagencita = (ImageView) view.findViewById(R.id.imagen_item);
Picasso.with(ctx).load(imagen).into(imagencita);
}
}
}
I don't know how to make this works.
I tried everything, but I just cant. Help me please. Thanks!.
try ChildEventLister class for this task.
mDatabaseEvento =
mDatabaseEvento.addChildEventListener(new ChildEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println("Estoy entrando aqui");
Log.i("gguwu", "Ayudaaaa");
GenericTypeIndicator<Map<String,String>> ImagenesType = new GenericTypeIndicator<Map<String, String>>() { };
Map<String,String> Imagenes = dataSnapshot.getValue(ImagenesType);
if (Imagenes!=null ) {
for (String imagen: Imagenes.values()) {
System.out.println(imagen);
viewHolder.setImagen(getApplicationContext(), imagen);
}
}
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError)
}

How to improve Flowable<Object> data reading from Firebase db using RxJava 2?

I have Recycler Viewer that displays data from Fire Base db however initial List contains around 4k elements. I am trying to show only first 15 elements instead of waiting for full list to be loaded however not sure how to do it.
I am trying to take(x) elements via Subscriber however it does not improve reading performance (it still waits for 4k elements from Firebase DB). How to speed up this?
Subscriber - Presenter
#Override
public void onBindViewHolder(final ListContentFragment.ViewHolder holder, int position) {
modelInterface.getDataFromFireBase("FinalSymbols")
.take(15)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<DataSnapshot>() {
#Override
public void accept(DataSnapshot dataFromDb) throws Exception {
//update TextView inside Recycler Viewer
holder.name.setText(dataFromDb.child(String.valueOf(holder.getAdapterPosition())).child("description").getValue().toString());
holder.description.setText(dataFromDb.child(String.valueOf(holder.getAdapterPosition())).child("categoryName").getValue().toString());
}
}
);
}
Publisher - source of Data (FireBase db)
#Override
public Flowable<DataSnapshot> getDataFromFireBase(final String childName) {
return Flowable.create(new FlowableOnSubscribe<DataSnapshot>() {
#Override
public void subscribe(final FlowableEmitter<DataSnapshot> e) throws Exception {
databaseReference.child(childName).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
e.onNext(dataSnapshot);
e.onComplete();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}, BackpressureStrategy.BUFFER);
I believe you need to use the method limitToFirst().
Something like this:
#Override
public Flowable<DataSnapshot> getDataFromFireBase(final String childName) {
return Flowable.create(new FlowableOnSubscribe<DataSnapshot>() {
#Override
public void subscribe(final FlowableEmitter<DataSnapshot> e) throws Exception {
databaseReference.child(childName).limitToFirst(15).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
e.onNext(dataSnapshot);
e.onComplete();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}, BackpressureStrategy.BUFFER);

Resources