How do I pass parameters/argument to a callback function? - java

A naive question as I am a bit new to programming.
I am Working on an Android application where I need to pass parameters to the callback method(Not sure if the verbiage is right).
I want the parameters/variables to be available to the Main Function. I am calling the Caller to invoke my main function and hence need the parameters to pass from the Caller.
something like the classic functions does
Example
method(param1, param2);
function method(param1, param2){
Log(param1 + param 2);
....
}
I need the below code to achieve the functionality as the above example
the code is as follows:
//Caller:-
getChioceList(new MyCallback() {
#Override
public void onCallback(ArrayList<String> value) {
Log.d("TAG", "Config CallBack " + value);
}
});
//Interface
public interface MyCallback{
void onCallback(ArrayList<String> value);
}
//Main function : I want some parameters to be passed to this method
public void getChioceList(final MyCallback myCallback) {
final ArrayList < String > result = new ArrayList < > ();
final DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
Query query = ref.child("Device").orderByChild("home").equalTo(homeID);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshots: dataSnapshot.getChildren()) {
result.add(dataSnapshots.getKey());
Log.i(TAG, "Config: get Input 3 " + result);
}
myCallback.onCallback(result);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {}
});
}
Please help...

Based on what i understand. Basically you want to pass something to a callback method.
I would suggest to create another class that will implement ValueEventListener.
Like so
public class SomeClassThatWillImplement implements ValueEventListener {
private String cVar1;
private String cVar2;
public SomeClassThatWillImplement (String param1, String parma2) {
this.cVar1 = param1;
this.cVar2 = param2;
}
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
//Do something with this.cVar1
//Do something with this.cVar2
for (DataSnapshot dataSnapshots : dataSnapshot.getChildren()) {
result.add(dataSnapshots.getKey());
Log.i(TAG, "Config: get Input 3 " + result);
}
myCallback.onCallback(result);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
//Do something with this.cVar1
//Do something with this.cVar2
}
}
To use above class,
public void getChioceList(final MyCallback myCallback) {
final ArrayList<String> result = new ArrayList<>();
final DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
Query query = ref.child("Device").orderByChild("home").equalTo(homeID);
query.addListenerForSingleValueEvent(new SomeClassThatWillImplement(param1, param2));
}
Hopefully this helps

Related

Get variable from inner function

I created an android app by using firebase database. This app needs to refresh date at once daily basis.
so I am getting date(long) from firebase database which I update from my admin. Date taking very important role in my app so I can't use device time to this.
So the point is I have created a class which gets this date from firbase database as shown below
Firebase Datebase img
public class time {
public String admin_time;
public String getAdmin_time() {
return admin_time;
}
public void setAdmin_time(String admin_time) {
this.admin_time = admin_time;
}
public time() {
FirebaseDatabase.getInstance().getReference().child("admin_time/admin_time")
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
setAdmin_time(Objects.requireNonNull(snapshot.getValue()).toString()); // i have set snapshot value to admin_time
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
Then I am trying to get admin_time value from another class
time time = new time();
String a = time.admin_time; // trying to call direct String
String b = time.getAdmin_time(); // trying to get value by using getter
myTextView.setText(a + " " + b);
but getting both values null
How can I get admin_time to another class?
Create a interface to provide time once it is fetched
interface TimeListener{
void onTime(String time);
}
Then in your time class (which should be Time ideally) pass the interface and get the time back when it's ready
public class Time {
private String admin_time;
public String getAdmin_time() {
return admin_time;
}
public void setAdmin_time(String admin_time) {
this.admin_time = admin_time;
}
public time(TimeListener timeListener) {//<-adding listener to constructor
FirebaseDatabase.getInstance().getReference().child("admin_time/admin_time")
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
setAdmin_time(Objects.requireNonNull(snapshot.getValue()).toString());
timeListener.onTime(admin_time);//<-passing time back
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
then while accessing do below
Time time = new Time(new TimeListener{
#Override
public void onTime(String t){
//use t here for admin_time
}
}

com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.Long to type (Model class)

I tried so hard but I Can't convert an object of type java.lang.Long to type (My Model class).
I am uploading my getDataFromFirebase() method below:
MainActivity.class
private void getDataFromFirebase() {
binding.projectRecycler.setHasFixedSize(true);
binding.projectRecycler.setLayoutManager(new LinearLayoutManager(activity));
binding.projectRecycler.setAdapter(adapter);
adapter = new ProjectAdapter(activity,projectDetailsBeanList);
projectDetailsBeanList = new ArrayList<>();
firebaseDatabase =FirebaseDatabase.getInstance();
databaseRef = firebaseDatabase.getReference("project_details");
DBListener = databaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
projectDetailsBeanList.clear();
for(DataSnapshot dataSnapshot : snapshot.getChildren()){
ProjectModel.ProjectDetailsBean projectDetailsBean = dataSnapshot.getValue(ProjectModel.ProjectDetailsBean.class);
projectDetailsBean.setKey(snapshot.getKey());
projectDetailsBeanList.add(projectDetailsBean);
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(activity, error.toString(), Toast.LENGTH_SHORT).show();
}
});
}
My Model Class
public class ProjectModel {
private ProjectDetailsBean project_details;
public ProjectDetailsBean getProject_details() {
return project_details;
}
public void setProject_details(ProjectDetailsBean project_details) {
this.project_details = project_details;
}
public static class ProjectDetailsBean {
private int architect_no;
private String client_name;
private String payment_received;
private String project_complete_date;
private String project_name;
private int project_no;
private String project_received_date;
private String key;
#Exclude
public String getKey() {
return key;
}
#Exclude
public void setKey(String key) {
this.key = key;
}
public int getArchitect_no() {
return architect_no;
}
public void setArchitect_no(int architect_no) {
this.architect_no = architect_no;
}
public String getClient_name() {
return client_name;
}
public void setClient_name(String client_name) {
this.client_name = client_name;
}
public String getPayment_received() {
return payment_received;
}
public void setPayment_received(String payment_received) {
this.payment_received = payment_received;
}
public String getProject_complete_date() {
return project_complete_date;
}
public void setProject_complete_date(String project_complete_date) {
this.project_complete_date = project_complete_date;
}
public String getProject_name() {
return project_name;
}
public void setProject_name(String project_name) {
this.project_name = project_name;
}
public int getProject_no() {
return project_no;
}
public void setProject_no(int project_no) {
this.project_no = project_no;
}
public String getProject_received_date() {
return project_received_date;
}
public void setProject_received_date(String project_received_date) {
this.project_received_date = project_received_date;
}
}
}
JSON data
{
"project_details" : {
"architect_no" : 1,
"client_name" : "pratik bharad",
"payment_received" : "yes",
"project_complete_date" : "22/09/2020",
"project_name" : "project of building",
"project_no" : 1,
"project_received_date" : "22/06/2020"
}
}
Error is:
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.Long to type com.psb.aurumdesign.ProjectModel$ProjectDetailsBean
You are getting the following error:
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.Long to type com.psb.aurumdesign.ProjectModel$ProjectDetailsBean
Because you are trying to convert the first child from your project_details node which is of type Long into an object of type ProjectDetailsBean, which is actually not possible. As I see in the JSON schema, under the project_details node, there is actually a single object, so there is no need to actually loop through the children in order to get the data. You can simply map that object directly into an object of type ProjectDetailsBean, as in the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference projectDetailsRef = rootRef.child("project_details");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
ProjectDetailsBean projectDetailsBean = dataSnapshot.getValue(ProjectDetailsBean.class);
Log.d("TAG", projectDetailsBean.getProject_name());
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage()); //Don't ignore potential errors!
}
};
projectDetailsRef.addListenerForSingleValueEvent(valueEventListener);
The result in the logcat will be the name of the project. If you only need, for example, the value of a single property, you can change the following line of code:
ProjectDetailsBean projectDetailsBean = dataSnapshot.getValue(ProjectDetailsBean.class);
To:
String projectName = dataSnapshot.child("project_name").getValue(String.class);

Retrieving Firebase Object Null Pointer Exception [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
I am getting a java.lang.NullPointerException error, and even though I checked mInternshipId and it is the same as I was expecting, it does not work.
This is my Firebase Content
This is my Internship Class
public class Internship {
private String internshipId;
private String internshipTitle;
private String internshipDesc;
private String internshipDate;
private String internshipImage;
private String internshipCreatorId;
public Internship() {
}
public Internship(String internshipId, String internshipTitle, String internshipDesc, String internshipDate, String internshipImage, String internshipCreatorId) {
this.internshipId = internshipId;
this.internshipTitle = internshipTitle;
this.internshipDesc = internshipDesc;
this.internshipDate = internshipDate;
this.internshipImage = internshipImage;
this.internshipCreatorId = internshipCreatorId;
}
public String getInternshipTitle() {
return internshipTitle;
}
public String getInternshipId() {
return internshipId;
}
public void setInternshipId(String internshipId) {
this.internshipId = internshipId;
}
public void setInternshipTitle(String internshipTitle) {
this.internshipTitle = internshipTitle;
}
public String getInternshipDesc() {
return internshipDesc;
}
public void setInternshipDesc(String internshipDesc) {
this.internshipDesc = internshipDesc;
}
public String getInternshipDate() {
return internshipDate;
}
public void setInternshipDate(String internshipDate) {
this.internshipDate = internshipDate;
}
public String getInternshipImage() {
return internshipImage;
}
public void setInternshipImage(String internshipImage) {
this.internshipImage = internshipImage;
}
public String getInternshipCreatorId() {
return internshipCreatorId;
}
public void setInternshipCreatorId(String internshipCreatorId) {
this.internshipCreatorId = internshipCreatorId;
}
}
This is where I am using it. It shows that mInternship is not been initialized. Thank you everyone in advance for your time.
//Get The Internship ID
Intent intent = getIntent();
mInternshipId = intent.getStringExtra(INTERNSHIP_ID);
//Initialize the Database Reference
databaseReference = FirebaseDatabase.getInstance().getReference().child("Internships").child(mInternshipId);
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
//Initialize Useful Variables
mInternship = dataSnapshot.getValue(Internship.class);
organizationId = mInternship.getInternshipCreatorId();
databaseReference = FirebaseDatabase.getInstance().getReference().child("Users").child("Organizations").child(organizationId);
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
internshipLocation = (String) dataSnapshot.child("location").getValue();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
The problem is at this line
mInternshipId = intent.getStringExtra(INTERNSHIP_ID);
you are not getting your extra, so you can't reference to an object inside your Firebase Database, and this is causing a null pointer at a null reference to retrieve the data.
Make sure that you are getting the extra in this class, put a debug point and see the value of mInternshipId
There is a way to check if mInternshipId is the problem.
databaseReference = FirebaseDatabase.getInstance().getReference().child("Internships").child(mInternshipId);
Run this line without mInternshipId and hardcode a child to get the data.
databaseReference = FirebaseDatabase.getInstance().getReference().child("Internships").child("-LchJYhSf3uwlv7AAXtr");
If that works with a hardcode child, you can assure that the problem is at your getStringExtra().

Android Java Firebase Querying objects into ArrayList

So I have been trying to download data from Firebase into an ArrayList:
public void updateOnce(){
animalList = new ArrayList<>();
Query query = mDatabase.orderByChild("id");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot messageSnapshot: dataSnapshot.getChildren()) {
SpottedAnimal pet = messageSnapshot.getValue(SpottedAnimal.class);
animalList.add(pet);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Debugger shows that the Object SpottedAnimal pet does get created and then inserted into the animalList that is a global ArrayList. But once I call the method:
public ArrayList<SpottedAnimal> getList(){
return animalList;
}
The animalList comes out empty on the other side.
FirebaseGetList() animalListHook = new FirebaseGetList();
animalListHook.updateOnce();
ArrayList<SpottedAnimal> animalList = animalListHook.getList();
onDataChange() is an asynchronous call.
So you have to consume the list as the event that adds an Animal object is triggered.
The client class should implement a Observer interface or a similar thing and as you instantiate FirebaseGetList, you should pass this (the client object):
In the client class :
public interface Notifiable {
void update();
}
public class ClientClass implements Notifiable {
public void foo(){
FirebaseGetList animalListHook = new FirebaseGetList();
animalListHook.updateOnce(this);
ArrayList<SpottedAnimal> animalList = animalListHook.getList();
}
#Override
public void update(){
// use the animalList here
}
}
in FirebaseGetList :
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot messageSnapshot: dataSnapshot.getChildren()) {
SpottedAnimal pet = messageSnapshot.getValue(SpottedAnimal.class);
animalList.add(pet);
}
this.update(); // method to notify
}
}
Note that using global variables is probably a design issue and should be corrected.
For example the update() method could pass the List of Animal as a parameter.

Java Android : How to convert an abstract class to a singleton with dagger

I have this helper class that constructs a pojo. I'm using firebase to fetch objects and create one object.
PROBLEM : This class is being called a lot, and I think it would be more economic to not keep creating its instance.
I tried doing it myself, but failed embarrassingly, still learning.
THE CLASS
public abstract class FetchPost implements ValueEventListener {
public abstract void event(Post post);
private Post post;
private String postId;
public FetchPost(String postId) {
AsyncTask.execute(() -> {
this.postId = postId;
Nodes.appRef("/posts/" + postId).addListenerForSingleValueEvent(this);
});
}
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
post = dataSnapshot.getValue(Post.class);
getUser();
}
#Override
public void onCancelled(DatabaseError e) {
}
private void getUser() {
Nodes.Users.profile(post.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot d) {
User user = d.getValue(User.class);
post.setUser(user);
getSound();
}
#Override
public void onCancelled(DatabaseError e) {
}
});
}
public void getSound() {
Nodes.appRef("sounds/" + post.getObjectId()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Sound sound = dataSnapshot.getValue(Sound.class);
sound.setSoundId(dataSnapshot.getKey());
post.setSound(sound);
event(post);
}
#Override
public void onCancelled(DatabaseError e) {
}
});
}
}
How can I construct this class such that I can use with Dagger as a singleton?
I tried using a normal class with an interface in place of the abstract method, but everytime i call FetchPost() with an interface as an event listener, all the previous call are replaced.

Categories

Resources