How to find out the error inside readData() Function? - java

I create a function that retrieves data from realtime firebase and Displays it to the user on android studio and when I run it, it displays null.
Here's the code :
public class ProcessSuccessed extends AppCompatActivity {
ActivityProcessSuccessedBinding binding;
DatabaseReference reference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityProcessSuccessedBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
}
private void readData(String name) {
reference = FirebaseDatabase.getInstance().getReference("users");
reference.child(name).get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
DataSnapshot dataSnapshot = task.getResult();
String name = String.valueOf(dataSnapshot.child("name").getValue());
binding.textView.setText(name);
}});}}

Related

Android Studio Binding Error Cannot resolve symbol

Heres the error
I want to display the text and images from firestore.
or are there other ways how to display data from firestore database to recyclerview.
AllProducts.java
public class AllProducts extends AppCompatActivity {
ActivityAllProductsBinding binding;
MyProductsAdapter myProductsAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityAllProductsBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
myProductsAdapter=new MyProductsAdapter(this);
binding.productsRecycler.setAdapter(myProductsAdapter);
loadProduct();
}
private void loadProduct(){
FirebaseFirestore.getInstance()
.collection("PRODUCTS")
.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
List<DocumentSnapshot> dsList=queryDocumentSnapshots.getDocuments();
for (DocumentSnapshot ds:dsList){
Product product=ds.toObject(Product.class);
myProductsAdapter.add(product);
}
}
});
}
}

Background firebase database scanner

I need to make background process in android studio, that will work when phone is turned off and will listen to the firebase realtime database and send notifications if the user data matches sent from another user firebase data.
I have a realtime database in which, when the "SOS" button is pressed, data is sent from which user the message goes and to whom.
That's how it looks like in Firebase console:
Firebase database {
Sos(all sos button clicks){
RandomID( like -N3AB5hwgkPO5kCqdaJf){
emailfrom(who clicked button)
emailto(user who will receive message)
time
}
}
}
i need to scan section "sos" all the time, and if emailto matches with my email, app will send notification.
I made the prototype with "extends service", but it doesn't even work, and does not perform any function.
public class SosListener extends Service {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String email = user.getEmail();
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
DatabaseReference dataBase = FirebaseDatabase.getInstance().getReference();
dataBase.child("Sos/").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot snapshot, String previousChildName) {
String emailTo = snapshot.child("emailTo").getValue(String.class);
if (emailTo == email) {
}
}
#Override
public void onChildChanged(#NonNull DataSnapshot snapshot, #Nullable String previousChildName) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot snapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot snapshot, #Nullable String previousChildName) {
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
Here is also MainActivity where I start this Service:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, SosListener.class));
}
}
How can I make it?

notifyItemInserted() is having same effect on list as notifyDataSetChanged() when I only want last item in list updated

The problem that I am having is that when a user adds a comment the entire list refreshes because I have notifyDataSetChanged(); set on the CommentAdapter. Everything jumps, and refreshes and I want it to be smoother, so I decided to use notifyItemInserted(); instead of notifyDataSetChanged();, but it isn't doing anything different.
notifyItemInserted(); should only update the last item or the newest item added to the list, so why is everything being refreshed/updated...?
Can someone tell me how to fix this? Only want last item added to list to be "added"/"updated"/whatever, not the entire list because if many people start commenting everything is always reloading...
In my readComments(); what I have now is mCommentAdapter.notifyItemInserted(mCommentList.size() - 1);, and what I had before was mCommentAdapter.notifyDataSetChanged();, but they are having the same effect. How can I fix this?
CommentsActivity
public class CommentsActivity extends AppCompatActivity {
private CommentAdapter mCommentAdapter;
private List<Comment> mCommentList;
private RecyclerView mRecyclerView;
EditText mAddComment;
ImageView mImageProfile;
TextView mPost;
String mPostId;
String mPublisherId;
String mNotificationId;
FirebaseUser mFirebaseUser;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_comments);
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(linearLayoutManager);
mCommentList = new ArrayList<>();
mCommentAdapter = new CommentAdapter(this, mCommentList, mPostId);
mRecyclerView.setAdapter(mCommentAdapter);
mAddComment = findViewById(R.id.add_comment);
mImageProfile = findViewById(R.id.image_profile);
mPost = findViewById(R.id.post_comment);
mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
mPost.setOnClickListener(v -> {
if (mAddComment.getText().toString().equals("")) {
Toast.makeText(CommentsActivity.this, "Can't send empty comments", Toast.LENGTH_SHORT).show();
} else {
addCommentNotification(mPublisherId, mPostId);
}
});
getImage();
readComments();
}
private void getImage() {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users").child(mFirebaseUser.getUid());
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
if (user != null)
Glide.with(getApplicationContext()).load(user.getImageurl()).into(mImageProfile);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void readComments() {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Comments").child(mPostId);
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mCommentList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Comment comment = snapshot.getValue(Comment.class);
mCommentList.add(comment);
}
mCommentAdapter = new CommentAdapter(CommentsActivity.this, mCommentList, mPostId);
mRecyclerView.setAdapter(mCommentAdapter);
mCommentAdapter.notifyItemInserted(mCommentList.size() - 1);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
I am guessing you should be using a ChildEventListener:
Your readComments() must be like this:
private void readComments() {
//your reference
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Comments").child(mPostId);
//the child listener
ChildEventListener listener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
// A new comment has been added
Comment comment = dataSnapshot.getValue(Comment.class);
mCommentList.add(comment);
//Notify adapter
mCommentAdapter.notifyItemInserted(mCommentList.size() - 1);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
//attach the listener
ref.addChildEventListener(listener);
}

add buttons to listview firebase arraylist strings android

I am new in programing
and this is my java code below
I want the simplest way to add button to each row of listview and relate it with that row firebase child (like a vote button for example) ...
should I custom simple_list_item_1 ?? or creat a new xml file .. please answer me in detail because like I said I am new in android
tnx for help
public class Main2Activity extends ListActivity {
String us , userId ;
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference();
ArrayList<String> listItems = new ArrayList<>();
ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
adapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,listItems);
setListAdapter(adapter);
userId = Profile.getCurrentProfile().getId() ;
us = Profile.getCurrentProfile().getName();
Toast.makeText(Main2Activity.this, "HI "+us,
Toast.LENGTH_SHORT).show();
ProfilePictureView profilePictureView;
profilePictureView = findViewById(R.id.ProfilePicture);
profilePictureView.setProfileId(userId);
ref.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
String value = childSnapshot.getValue(String.class);
listItems.add(value);
}
adapter.notifyDataSetChanged();
}
#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) {
}
});
}
}
android.R.layout.simple_list_item_1 is a reference to an built-in XML layout document that is part of the Android OS which containt only one TextView, so if you want to add another view (e.g. button) you need to create your own layout.

Is this my code or Firebase code causing this leak?

I am getting a lot of memory leaks in an application I created. I created a very simple app to reproduce the problem. This application just makes a reference to the FirebaseDatabase and sets up a ChildEventListener. When the user clicks the button it adds a record to the database, and starts a new activity which does System.gc().
Pressing the button multiple times will cause Leak Canary to generate a dump.
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private FirebaseDatabase firebaseDatabase;
private DatabaseReference dbRef;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
firebaseDatabase = FirebaseDatabase.getInstance();
dbRef = firebaseDatabase.getReference("leak");
dbRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
findViewById(R.id.btn_leak).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dbRef.child(UUID.randomUUID().toString()).setValue("Yes");
Intent leakIntent = new Intent(getApplicationContext(), LeakActivity.class);
startActivity(leakIntent);
}
});
}
}
LeakActivity.java:
public class LeakActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.leak);
System.gc();
}
}
Due to the post limit, the leak canary log is here.
Am I doing something wrong in my code, or is this related to Firebase?
EDIT: #qbix's answer seemed to work. For others, here is the working version of MainActivity.java:
public class MainActivity extends AppCompatActivity {
private FirebaseDatabase firebaseDatabase;
private DatabaseReference dbRef;
private ChildEventListener dbListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
firebaseDatabase = FirebaseDatabase.getInstance();
dbRef = firebaseDatabase.getReference("leak");
dbListener = getDbListener();
dbRef.addChildEventListener(dbListener);
findViewById(R.id.btn_leak).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dbRef.child(UUID.randomUUID().toString()).setValue("Yes");
Intent leakIntent = new Intent(getApplicationContext(), LeakActivity.class);
startActivity(leakIntent);
}
});
}
#Override
protected void onStop() {
dbRef.removeEventListener(dbListener);
super.onStop();
}
private ChildEventListener getDbListener(){
return new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
}
#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) {
}
};
}
}
I haven't used LeakCanary, so this is just an educated guess.
ChildEventListeners need to be unregistered when they are no longer needed. Often listeners are added and removed in activity lifecycle methods, such as onCreate() and onDestroy(). Instead of creating an anonymous listener, create an object of that type and remove it using Query.removeEventListener() when no longer needed to see if that eliminates the leak report.
I think that is better to add/remove listeners within the onStart()/onStop() or the onCreate()/onDestroy() callbacks respectively.
If a listener was added in onCreate() and removed in onStop() there could occur a situation when an activity will be restored without of calling the onCreate() but with calling of onStart() and listener will not be set.
https://developer.android.com/images/activity_lifecycle.png

Categories

Resources