The data is saved correctly, as you can see in the following image:
I use this code:
btnDatos.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String name = nameTextView.getText().toString();
String email = emailTextView.getText().toString();
String id = idTextView.getText().toString();
String idJuego = idffTextView.getText().toString();
Map hopperUdates = new HashMap();
hopperUdates.put("name", name);
hopperUdates.put("email", email);
hopperUdates.put("id", id);
hopperUdates.put("idFreeFire", idJuego);
mDatabase.child("Usuario").child(mAuth.getCurrentUser().getUid()).updateChildren(hopperUdates);
}
});
And to obtain the data I use the following code:
mDatabase.child("Usuario").child(mAuth.getCurrentUser().getUid()).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
int idJuego = dataSnapshot.getValue(Integer.class);
idffTextView.setText(idJuego);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
But it does not show the data and when I test it on the device the app is closed. What would be the error?
If you want all data then create model class and then stored datasnapshot into that model class like this
Model model = dataSnapshot.getValue(Model.class);
Or you want single data then just get the child like this
String idJuego = dataSnapshot.child("childname").getValue().toString;
And then set that string into textView.
try to convert from Integer to string...
int idJuego = dataSnapshot.getValue(Integer.class);
idffTextView.setText(String.valueOf(idJuego ));
Because you are saving the uid as the key of your user object and in the same time as a property within the user object, to set that id to your idffTextView, please use either the following lines of code:
String idJuego = dataSnapshot.getkey();
idffTextView.setText(idJuego);
Or:
String idJuego = dataSnapshot.child("id").getValue(String.class)
idffTextView.setText(idJuego);
Please note, that in both cases the id is of type String and not int.
Related
I stored datas from the database to an arrayList called nameList.
Within the function 'get_spinner_info', the values are successfully stored within the nameList.
However, there is no value for nameList outside of this function.
The error code is
" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 ".
I really need your help.
public class my_Item {
private Context context;
private FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference datebaseReference = firebaseDatabase.getReference();
ArrayList<String> nameList = new ArrayList<String>();
// Get the value from the database and put them in the 'nameList'.
//In this code, I can successfully check the value within the 'nameList'.
public void get_spinner_info(String brand, String item, String prod_key){
datebaseReference.child(brand).child(item).child(prod_key).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.child("myValue").getChildren()) {
String prod_name = ds.getValue().toString();
nameList.add(prod_name);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
// But the nameList is empty in this part.
public void callFunction(final String brand, final String item, final String product_name, final String product_key, final int product_Num) {
get_spinner_info(brand, item, product_key);
Log.d("Spinner namelist : ", nameList.get(0));
}
}
get_spinner_info method starts and ASYNCHRONOUS data loading (registers lsitener), thus onDataChange will get called after Log.d("Spinner nameList : ", nameList.get(0));
your data will be available only after onDataChange call, which may take some time. get_spinner_info just starts loading your data, doesn't means that all data will be available just after method call ends
put this on the end of onDataChange (after current for loop) to check your items available/present in array
for (String name : nameList) Log.d("Spinner", "name: " + name);
Synchronization problem cause this kind of error
if you already have data do this
create interface class
public interface DataCallback {
public void reciveData(ArrayList<String> nameList ,boolean isOk);
}
In your class my_Item call the interface like this
public void get_spinner_info(String brand,String item,String prod_key,DataCallback callback){
datebaseReference.child(brand).child(item).child(prod_key).addListenerForSingleValueEvent(new ValueEventListener(){
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot){
for(DataSnapshot ds:dataSnapshot.child("myValue").getChildren()){
String prod_name=ds.getValue().toString();
nameList.add(prod_name);
}
// here you should check if the result available or NOT to prevent null exceptions
if(nameList.size()>0){
callback.reciveData(nameList,true);// true and false used to check data if available or null
}
else{
callback.reciveData(nameList,false);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError){
}
});
}
Now when you call get_spinner_info you need the callback Like this
get_spinner_info(brand, item, product_key,new DataCallback() {
#Override
public void callback(ArrayList<String> nameList, boolean isOk) {
if (isOk){
/// you have all data recived
Log.d("Spinner namelist : ", nameList.get(0));
}else {
// no data available
Log.i("TAG", "callback: No Data Available");
}
}
}););
I am developing an Attendance App. I want to retrieve students list with number of presents and populate it in a list view.
I have tried the below code but i am getting number of presents of one specific student.
DatabaseReference ref =
FirebaseDatabase.getInstance().getReference().child("Students
Attendance").child(selectedItem).child(id).child(subject);
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() != null) {
Userlist.add(dataSnapshot.getValue().toString());
addStudents(Userlist);
}else {
Toast.makeText(getApplicationContext(), "****NO Record
FOUND****", Toast.LENGTH_LONG).show();
}
}
I expect the output as a list of students with their number of presents populated in list view.
My firebase Structure
I want this kind of result
Since you are making an app that counts a number of presents of a particular student. You can do it this way:
First you can set the value to be stored in the database as :
mFirebaseDatabaseReference.push().setValue(new String[]{student_name,attendance})
This stores the data as :-
Sam,70 and
Mike,75
Now retrive that data using ChildEventListener:
mChildEventListener = new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
String data = dataSnapshot.getValue();
mMyAdapter.add(data);
);
One thing to not here is that, you dont necessarily need to put the student_id as we using the push() method here so it gives every child a new id so that we don't have to worry about the data being disturbed for students with the same name or marks.
ref.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot.exists()) {
String value = dataSnapshot.getValue().toString();
String key = dataSnapshot.getKey();
String record = key + ": " + value;
Userlist.add(record);
addStudents(Userlist);
}
It worked for me.
I have an authenticateID method which searches in the database to find a match and does something. I guess it will take long to explain so here is my code:
public boolean authenticateStudentID() {
boolean success = true;
final String studentID = etStudentID.getText().toString().trim();
final String module = etModule.getText().toString().trim();
final String degree = etDegree.getText().toString().trim();
final String room = etRoom.getText().toString().trim();
final String email = etEmail.getText().toString().trim();
final String fullname = etfullname.getText().toString().trim();
final String loginID = etLoginID.getText().toString().trim();
if (success) {
databaseRef.addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) { // wtf is this advanecd for loop
//map string string because our key is a string and value is a string, map has a key and value object
Map<String, String> map = (Map) snapshot.getValue();
if (map != null) { //if the values and keys are not null
String studentIDMatch = map.get("studentID");
// Log.v("E_VALUE", "students ID entered : " + studentIDMatch);
// Log.v("E_VALUE", "students ID from db: " + studentID);
if (studentID.equals(studentIDMatch)) {
String uniqueKey = databaseRef.push().getKey();
NewStudentAccounts sam = new NewStudentAccounts
(studentID, loginID, email, fullname, module, degree, room);
databaseRef.child(uniqueKey).setValue(sam);
Toast.makeText(getApplicationContext(), "Your account registration has been successful!", Toast.LENGTH_SHORT).show();
startActivity(new Intent(getApplicationContext(), LoginActivity.class));
} else {
Toast.makeText(getApplicationContext(), "Invalid Student Credentials Entered!!", Toast.LENGTH_SHORT).show();
}
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
return success;
I want to know how I can reuse this method for another class instead of copy and pasting code. Please guide me, I really appreciate it.
private void addNewStudent() {
findViewById(R.id.buttonAddStudent).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
View addStudentActivityDialog = LayoutInflater.from(LecturerAccount.this).inflate(R.layout.activity_add_student,null);
etStudentName = addStudentActivityDialog.findViewById(R.id.editTextStudentName);
etStudentUserID = addStudentActivityDialog.findViewById(R.id.editTextStudentUserID);
AlertDialog.Builder addStudentBuilder = new AlertDialog.Builder(LecturerAccount.this);
addStudentBuilder.setMessage("STAR").setView(addStudentActivityDialog).setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
String studentName = etStudentName.getText().toString();
String studentID = etStudentUserID.getText().toString();
registerActivity = new RegisterActivity(); //calling the instance of the class here
if (registerActivity.authenticateStudentID() == true){
studentarray.add(studentName);
}
}
}).setNegativeButton("cancel", null).setCancelable(false);
AlertDialog newStudentDialog = addStudentBuilder.create();
newStudentDialog.show();
}
});
}
My if statement here calling the function, I am totally clueless here.
Since onDataChange(DataSnapshot dataSnapshot) is an asynchronous callback event from firebase you must implement your own callback method to get notified of the result.
One approach would be to use interfaces.
create a separate class Auth
public class Auth {
public static void authenticateStudentID(final String studentID, final AuthListener listener) {
DatabaseReference databaseRef = FirebaseDatabase.getInstance().getReference("your reference");
databaseRef.addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) { // wtf is this advanecd for loop
//map string string because our key is a string and value is a string, map has a key and value object
Map<String, String> map = (Map) snapshot.getValue();
if (map != null) { //if the values and keys are not null
String studentIDMatch = map.get("studentID");
if (studentID.equals(studentIDMatch)) {
if (listener != null)
listener.onAuthSuccess();
} else {
if (listener != null)
listener.onAuthFailure();
}
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
if (listener != null)
listener.onAuthFailure();
}
});
}
public interface AuthListener {
void onAuthSuccess();
void onAuthFailure();
}
}
And then call it by
Auth.authenticateStudentID(studentId, new Auth.AuthListener() {
#Override
public void onAuthSuccess() {
}
#Override
public void onAuthFailure() {
}
});
wherever required
As the method you want to reuse should be "public" first of all. It simply means that it can be publically accessed among other classes of that project. And after making it public you can simply refer it using the class name.
Here is an example of this :
Class2 instance = new Class2();
instance.publicMehtodToBeAcessedInThisClass(any parameters);
But in your case, you will have to copy and paste the code to another class file only.
Reason: Because you are fetching data from the layout file of your Java file and this will crash the app. Either you should further modularize your code and handle this by making a separate function for fetching all this data. Otherwise, copy pasting only a method from one class to another will not make your application run into any performance issue or lags.
Access modifier is incorrect. Good old java doc will explain better than me:
access modifiers
In order to access it, you have to create an instance like so:
YourClass yourClass = new YourClass();
yourCLass.authenticateStudentID();
The YourClass is usually the name of the file where this code you pasted located in.
From what you've shown, there are two issues you need to deal with:
As noted, having it private doesn't do you much good when it comes to reuse.
It looks like the databaseRef object is a class property. So you'll need to pass this in, rather than rely on the class property for that class, since you want to use it from another class. (Or you can put this method, and the databaseRef property, in a superclass and have your two classes inherit from it.)
In general - think about what your method needs to do, and then what it needs to do that. Those should shape how you make the method more usable from other parts of your code.
I'm trying to fetch some data from Firebase, but getting this error: java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map while trying to do so.
Here's what I'm trying;
public void retrieveUserCounterAccepted() {
databaseReferenceUsers = FirebaseDatabase.getInstance().getReferenceFromUrl("https://appname-e1a13.firebaseio.com/users/");
databaseReferenceUsers.child(uid).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
// error on the line below
newRequestAcceptedCounter = (Map<String, String>) dataSnapshot.getValue();
// error on line above
String requestAcceptedCounter = newRequestAcceptedCounter.get("requestsAccepted");
String requestsPostedCounter = newRequestAcceptedCounter.get("requestsPosted");
Menu menu = navigationView.getMenu();
MenuItem requests_posted = menu.findItem(R.id.requests_posted_counter);
requests_posted.setTitle(requestsPostedCounter);
MenuItem requests_accepted = menu.findItem(R.id.requests_accepted_counter);
requests_accepted.setTitle(requestAcceptedCounter);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
newRequestAcceptedCounter = (Map<String, String>) dataSnapshot.getValue();
String requestAcceptedCounter = newRequestAcceptedCounter.get("requestsAccepted");
String requestsPostedCounter = newRequestAcceptedCounter.get("requestsPosted");
Menu menu = navigationView.getMenu();
MenuItem requests_posted = menu.findItem(R.id.requests_posted_counter);
requests_posted.setTitle(requestsPostedCounter);
MenuItem requests_accepted = menu.findItem(R.id.requests_accepted_counter);
requests_accepted.setTitle(requestAcceptedCounter);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
What's going wrong here?
Please let me know.
The specific class of the object returned by getValue() will be one of the supported JSON types:
Boolean
String
Long
Double
Map<String, Object>
List<Object>
The class is determined by the format (or other embedded type info) of the value stored in the database.
In your case, the value stored is a String. It cannot be cast to a Map.
Use the Firebase Console to view the values stored as the children of uid to confirm they are what you expect. Perhaps you did not intend to store strings, but that it what is there.
Update
Instead of a ChildEventListener you need to use a ValueEventListener. If am understanding your database structure correctly, a uid has children requestsAccepted and requestsPosted. Using a ChildEventListener, the callbacks will fire when either of those change and will return the simple string value of the changed child. Your callback code is expecting the map of all the children of uid. You can get this with a ValueEventListener on uid.
You could also continue to use a ChildEventListener, but on a reference that is one level up:
databaseReferenceUsers.addChildEventListener(...)
How Can I get ArrayList of Java Objects of all Childs from Firebase using updated firebase commands, currently I am using below approach but not able to get the list.
ValueEventListener postListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get Post object and use the values to update the UI
if(dataSnapshot!=null){
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
UserDataClass post = postSnapshot.getValue(UserDataClass.class);
members.add(post);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
}
};
mDatabaseRef.addValueEventListener(postListener);
below is datasnapshot which is returning from firebase but I am not able to get the desired result out of it.
DataSnapshot { key = 12345, value = {Members={00000000={phoneNo=00000000, longitude=73.0703307, latitude=33.6396975, password=qwertyuiop, CName=00000000, admin=true, name=Anwar Kamal}, 03028084374={phoneNo=03028084374, longitude=73.0701292, latitude=33.6397129, password=qwerty, CName=00000000, admin=false, name=Nehal Khan}, 03028084516={phoneNo=03028084516, longitude=73.0702659, latitude=33.6397622, password=qwerty, CName=03035356317, admin=false, name=Jamal Khan}}} }
all i want is list of all members
and my java object is
public class UserDataClass {
public double latitude;
public double longitude;
public String Name="";
public String password="";
public String phoneNo="";
public String CircleName="";
public boolean isAdmin=false;
}
The ValueEventListener has another purpose.
You should use ChildEventListener and also dataSnapshop.getValue() to implement what you want, for example:
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
UserDataClass post = postSnapshot.getValue(UserDataClass.class);
members.add(post);
}
//...
Note:
You should use the listener with the current firebase_referance to the Users table. Hence you should replace
mDatabaseRef.addValueEventListener(postListener);
with
mDatabaseRef.child("Members").addChildEventListener(childEventListener);
notice that your full path of the Members table is colored and i couldn't figure the path.
You can find the whole documentation here
good luck