I have seen many other similar questions and also tried their method but still its not working.
My getFirebase function on a Click Listener :
private void getFirebase() {
firebaseDatabase = FirebaseDatabase.getInstance();
reference = firebaseDatabase.getReference().child("Questions/m1");
List<String> list = new ArrayList<>();
Log.d("QuizFragment", "getfirebase");
reference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d("QuizFragment", " Snapshots");
list.add(dataSnapshot.getValue().toString());
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("QuizFragment", "error " + databaseError.toString());
}
});
Log.d("QuizFragment","debug");
}
My Logcat is showing getFirebase and then directly debug message.
I have seen many answer to wait for execution of SingleEvent but I have waited for many time still its not showing. Note : I am running app on emulator
addListenerForSingleValueEvent will get the data from the local disk cache.If you don't have any data in your cache you won't get any data.i believe that's why you could not get into onDataChange(). so first get data at least once like this
firebaseDatabase.getReference().child("Questions/m1")
.get()
.addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (!task.isSuccessful()) {
Log.e("firebase", "Error getting data", task.getException());
}
else {
Log.d("firebase", String.valueOf(task.getResult().getValue()));
}
}
});
//then use cache data.
reference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d("QuizFragment", " Snapshots");
list.add(dataSnapshot.getValue().toString());
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d("QuizFragment", "error " + databaseError.toString());
}
});
Related
I making an Attendance App.
In the app there is a function to know how many event an users already attend and what event they attend.
What i want is something like this (i dont know if it work or there is a better way):
private void fetchSpecificEvent() {
//Fetch event that user already attend
FirebaseRecyclerOptions<ModelEvent> options = new FirebaseRecyclerOptions.Builder<ModelEvent>()
.setQuery(referenceForSpecificEvent, snapshot -> new ModelEvent(
Objects.requireNonNull(snapshot.child("eventID").getValue()).toString(),
...
...
...
)
.build();
...
}
private void getAttendanceCount(){
//Get how many event user already attend
referenceForCount.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
attendanceCount = (int) snapshot.getChildrenCount();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
The main problem is i dont know what reference i use on: referenceForSpecificEvent and referenceForCount
This the JSON:
This the full JSON : https://pastebin.com/k65jhMUC
Sorry for the title, i dont know the keyword for it.
I found the way to do it. Probably not the best (because i cant really explain what i want) but it works.
reference = FirebaseDatabase.getInstance().getReference().child("Attendance");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()){
for (DataSnapshot eventSnapshot: dataSnapshot.getChildren()) {
//Get Event ID
Log.i(TAG, eventSnapshot.getKey());
for (DataSnapshot userSnapshot: dataSnapshot.child(Objects.requireNonNull(eventSnapshot.getKey())).getChildren()) {
//Get User ID
//Log.i(TAG, userSnapshot.getKey());
if(Objects.equals(userSnapshot.getKey(), stringEmail)){
intCount++;
listEvent.add(eventSnapshot.getKey());
}
}
}
}
else{
Log.i(TAG, "No Value Found");
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.d(TAG, error.getMessage()); //Don't ignore errors!
}
});
I want to check that if classection=Six:B already exist in firebase database then it show toast message please guide I am trying to solve this from 3 days but I cannot solve it Here is my code it doesnot show any error or toast
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users");
Query query = ref.child("Students");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String classsection=""+dataSnapshot.child("classsection").getValue();
if(classsection.equals("Six:B"))
{
Toast.makeText(MaintabclasActivity.this, "Class Six B is Already Exist",
Toast.LENGTH_LONG).show();
}
else
{
// updateclasfiveb();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(MaintabclasActivity.this, "error",
Toast.LENGTH_LONG).show();
}
});
Instead of addListenerForSingleValueEvent ,use onCompleteListener to get data once if you really wants access real time database. because addListenerForSingleValueEvent is for cache data.
// If you have child node id to go through each node use below method.
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users");
ref.child("Students").child("node_id_under_student").get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (!task.isSuccessful()) {
Log.e("firebase", "Error getting data", task.getException());
}
else {
Log.d("firebase", String.valueOf(task.getResult().getValue()));
}
}
});
// Or use query method with ValueEventListener to listen for changes in database.
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users/Students");
Query databaseQuery= ref.orderByChild("classsection").equalTo("Six:B");
databaseQuery.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
String classsection=""+dataSnapshot.child("classsection").getValue();
if(classsection.equals("Six:B"))
{
Toast.makeText(MaintabclasActivity.this, "Class Six B is Already Exist",
Toast.LENGTH_LONG).show();
}
else
{
// updateclasfiveb();
}}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
// ...
}
});
A query in Firebase consists of two parts:
A call to order the child nodes of a path on its key, or a certain property.
A call to then filter the child nodes down by a certain value or range.
In your case:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users/Students");
Query query = ref.orderByChild("classsection").equalTo("Six:B");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
Toast.makeText(MaintabclasActivity.this, "Class Six B is Already Exist", Toast.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(MaintabclasActivity.this, "error", Toast.LENGTH_LONG).show();
}
});
I'm trying to download firebase data in for loop then notify RecyclerView adapter. But since firebase runs async task. I'm not able to do that. How to force firebase to run synchronously or how to know all firebase data is downloaded.
Example code:
for(int i=0;i<list.size();i++){
FirebaseDatabase.getInstance().getReference().child(list.get(i)).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Post post = dataSnapshot.getValue(Post.class);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
//When all data is downloaded
adapter.notifyDataSetChanged();
There is no way to force Firebase to read the data synchronously.
But if all you want to do is know when all data has been loaded, you can keep a simple counter of the number of items that successfully loaded:
int completedCount = 0;
for(int i=0;i<list.size();i++){
FirebaseDatabase.getInstance().getReference().child(list.get(i)).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Post post = dataSnapshot.getValue(Post.class);
completedCount = completedCount + 1;
if (completedCount == list.size()) {
adapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
}
[model class is returning null, data is coming from Firebase database but upon getting imageUrl its giving null.
Actually, I am trying to get images urls from database which are previously saved.
firebaseDatabase=FirebaseDatabase.getInstance();
databaseReference=firebaseDatabase.getInstance().
getReference("Catagories");
mupload=new ArrayList<>();`
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot post : dataSnapshot.getChildren())
{
Upload upload=post.getValue(Upload.class);
mupload.add(upload);
}
customQuoteAdapter=new CustomQuoteAdapter( Images.this,
mupload);
recyclerView.setAdapter(customQuoteAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getApplicationContext(),
"ERROR"+databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
You have a bussiness (sic) level in your JSON, that you're not handling in your code. The simplest way to fix this is to attach your listener to that bussiness node:
databaseReference=firebaseDatabase.getInstance().getReference("Catagories/Bussiness");
mupload=new ArrayList<>();`
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot post : dataSnapshot.getChildren()) {
Upload upload=post.getValue(Upload.class);
mupload.add(upload);
}
customQuoteAdapter=new CustomQuoteAdapter( Images.this, mupload);
recyclerView.setAdapter(customQuoteAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getApplicationContext(), "ERROR"+databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
If you want to get all URLS for all nodes under Categories, you'll need to add a loop inside onDataChange. Something like:
databaseReference=firebaseDatabase.getInstance().getReference("Catagories");
mupload=new ArrayList<>();`
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot categorySnapshot : dataSnapshot.getChildren()) {
for(DataSnapshot linkSnapshot : categorySnapshot.getChildren()) {
Upload upload=linkSnapshot.getValue(Upload.class);
mupload.add(upload);
}
}
customQuoteAdapter=new CustomQuoteAdapter( Images.this, mupload);
recyclerView.setAdapter(customQuoteAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getApplicationContext(), "ERROR"+databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
Should it be?
public String getImageUrl() {
return this.imageUrl;
}
I am working on a project where user request for our valet services and on the other end valet accepts request.
I am using using Firebase as backend and on request customer uid is save on 'request' child.
When valet accepts request, customer uid should move from 'request' node to 'on progress' node.
How can i do that?
I recommend using this :
public void moveFirebaseRecord(Firebase fromPath, final Firebase toPath)
{
fromPath.addListenerForSingleValueEvent(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
toPath.setValue(dataSnapshot.getValue(), new Firebase.CompletionListener()
{
#Override
public void onComplete(FirebaseError firebaseError, Firebase firebase)
{
if (firebaseError != null)
{
System.out.println("Copy failed");
}
else
{
System.out.println("Success");
}
}
});
}
#Override
public void onCancelled(FirebaseError firebaseError)
{
System.out.println("Copy failed");
}
});
}
This come from this source : https://gist.github.com/katowulf/6099042 . I used it several times in my JavaEE code and also in my android app.
You pass your fromPath and toPath. This is a copy tought and not a move, so the original will remain at his original place too. If you would like to delete, you can do a set value on the fromPath just after the System.out.println("Success"); .
As of compile firebase-database:11.0.1, this is the same function with the new class references (https://firebase.google.com/support/guides/firebase-android July 05 2017)
private void moveGameRoom(final DatabaseReference fromPath, final DatabaseReference toPath) {
fromPath.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
toPath.setValue(dataSnapshot.getValue(), new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError firebaseError, DatabaseReference firebase) {
if (firebaseError != null) {
System.out.println("Copy failed");
} else {
System.out.println("Success");
}
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
If you want to perform a move which also erases the original, you might make use of the following snippet:
// In this piece of code, "fromPath" and "toPath" parameters act like directories.
private void removeFromFirebase(final DatabaseReference fromPath, final DatabaseReference toPath, final String key) {
fromPath.child(key).addListenerForSingleValueEvent(new ValueEventListener() {
// Now "DataSnapshot" holds the key and the value at the "fromPath".
// Let's move it to the "toPath". This operation duplicates the
// key/value pair at the "fromPath" to the "toPath".
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
toPath.child(dataSnapshot.getKey())
.setValue(dataSnapshot.getValue(), new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if (databaseError == null) {
Log.i(TAG, "onComplete: success");
// In order to complete the move, we are going to erase
// the original copy by assigning null as its value.
fromPath.child(key).setValue(null);
}
else {
Log.e(TAG, "onComplete: failure:" + databaseError.getMessage() + ": "
+ databaseError.getDetails());
}
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG, "onCancelled: " + databaseError.getMessage() + ": "
+ databaseError.getDetails());
}
});
}
you can listen to value event on your child you want to copy it ,, and #onDataChange get reference of new child and set value dataSnapshot to this child like below sample code
FirebaseDatabase.getInstance().getReference("childYouWantToCopy")
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
FirebaseDatabase.getInstance().getReference("ChildCopyTo").setValue(dataSnapshot.getValue());
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});