Retrieving data from Firebase in Android activity - java

I read many threads regarding how to get data from Firebase database instance, but none of them worked for me.
My code in the activity:
public class Violations extends AppCompatActivity
{
TextView textView7;
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference dbref = database.getReference("save");
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_violations);
textView7 = findViewById(R.id.textView7);
dbref.addValueEventListener(new ValueEventListener()
{
ArrayList<String> Violations = new ArrayList<>();
#Override
public void onDataChange(DataSnapshot dataSnapshot)
{
for (DataSnapshot postSnapshot: dataSnapshot.getChildren())
{
Violations.add(postSnapshot.getValue().toString());
System.out.println(postSnapshot.getValue().toString());
}
for(int i=0; i < Violations.size(); i++)
{
textView7.setText(textView7.getText() + Violations.get(i) + System.lineSeparator());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});
}
}
There is no error in there, but no data displays. I am pretty sure, my problem is connecting to the right instance and retrieving the data.
Firebase data, are like this:
Can someone please help me in there?
Thanks you in advance.

Initialize the Firebase database & the DatabaseReference inside onCreate() method:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_violations);
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference dbref = database.getReference("save");
...
..
Also, the reference you are getting is save but the Firebase database shows that is : you violate .... You may try changing the name to save or getting the right data : you violate ....

Try to use addListenerForSingleValue() instead of addValueEventListener(). Hope it helps. And change your firebase link save to you violate your own speed limit with

I cannot see in your database schema o reference named save but I see one named You violate your own speed limit with, which mush be used in your reference in order to be able to get data from the database. So to solve this, please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference ref = rootRef.child("You violate your own speed limit with");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
ArrayList<String> violations = new ArrayList<>();
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String speed = ds.getValue(String.class);
violations.add(speed);
Log.d(TAG, speed);
}
//Do what you need to do with y our violations list
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage());
}
};
ref.addListenerForSingleValueEvent(valueEventListener);
The result in your logcat will be all those values:
3 km / h at time: ...
3 km / h at time: ...
//an so on

Related

How to retrieve data from Firebase when data didn't change

I'm quite confused with listeners and Firebase. I understand that the only way to retrieve data from Firebase is listeners. I'm using addListenerForSingleValueEvent to retrieve the username value, which it works well only when that value changes or when I execute this code for a second time. Username value shouldn't change at all but I still need to read it often. How do you read from FB when no changes had occurred?
FirebaseAuth mAuth = FirebaseAuth.getInstance();
FirebaseUser user = mAuth.getCurrentUser();
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("forum")
.child("level1exercice1").child("post").child("username");
myRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
value = snapshot.getValue(String.class);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
Have you tried reading it as a snapshot and then storing it as a cookie for future use?
The following code is from Firebase Docs:
FirebaseDatabase.DefaultInstance
.GetReference("Leaders").OrderByChild("score").LimitToLast(1)
.ValueChanged += HandleValueChanged;
}
void HandleValueChanged(object sender, ValueChangedEventArgs args) {
if (args.DatabaseError != null) {
Debug.LogError(args.DatabaseError.Message);
return;
} // Do something with the data in args.Snapshot
}

Android Firebase database limitToLast(1) weird behaviour

I have a very simple code:
// get users poll date, and set in relevant text view
Query query = gameRef.child("users_loto").child("zaalkIb4W0V7MGbekLhqjP34IQi1").orderByChild("pollRank").limitToLast(1);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
nDate = Long.parseLong(ds.child("pollRank").getValue().toString().substring(0, 14));
user_result.setText(String.valueOf(nDate));
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
};
query.addListenerForSingleValueEvent(valueEventListener);
I ordered it by pollRank - it is the same number as the child name.
It seems to return the last value of the relevant node:
But instead, it always returns the one before :
A very weird behavior...
Any thoughts about why it happens?
Tnx for #ShehanWisumperuma!
gameRef.keepSynced(true) was the correct answer to my issue!!!
Tnx for all of you who tried to help me!

Transfer list size from Activity to Adapter class and update TextView with that quantity

I have a method in my FollowersActivity class getFriendsAttendingEvent(); which returns the number of users that adhere to two specific criteria. Now, those users populate a list when I click on a TextView which I have in my Adapter class PostAdapter.
I need to get that number (quantity) of users that are in the list and I want to put it in the TextView in my PostAdapter class. I want to do something like holder.textView.setText(*list.size()), but how can I get that number from my FollowersActivity over to my PostAdapter class?
I know from the Adapter class I transfer data between the two classes by using Intent, but to go the other way around, would I have to create an interface or something? SharedPreferences perhaps? I don't know...
How would I send this line, String number = String.valueOf(mIdList.size()); over to my PostAdapter? This is the number that I need.
FollowersActivity
private void getFriendsAttendingEvent() {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Attending Event").child(mPostId);
reference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mIdList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
mIdList.add(snapshot.getKey());
}
DatabaseReference reference1 = FirebaseDatabase.getInstance().getReference("Following").child(mFirebaseUser.getUid());
reference1.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mIdList1.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
for (String id : mIdList) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (Objects.equals(snapshot.getKey(), id)) {
mIdList1.add(snapshot.getKey());
}
}
}
}
if (mIdList1.size() > 0) {
String number = String.valueOf(mIdList.size());
Log.d("NUMBEROFUSERS", number);
showUsers();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
PostAdapter
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, int position) {
mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
final Post post = mPost.get(position);
holder.friendsAttendingEvent.setOnClickListener(v -> {
Intent intent = new Intent(mContext, FollowersActivity.class);
intent.putExtra("id", post.getPostid());
intent.putExtra("postid", post.getPostid());
intent.putExtra("publisherid", post.getPublisher());
intent.putExtra("title", "Friends Attending");
mContext.startActivity(intent);
});
So what I have understood so far is that,
You have a PostAdapter (that displays data related to a post just like in most of the social media applications) and this Adapter has a TextView that represents the number of followers.
So, the navigation structure might be like this:
PostAdpater --- (Click on the TextView) ---> FollowersActivity
By Clicking the TextView representing the number of followers we shift to the FollowersActivity, and there you might be displaying the details of Followers. But the problem is, that you are fetching the data on the FollowersActivity where as you required it before the navigation on the PostAdapter.
The Only Simple Solution that I am able to figure out is that you move your query function getFriendsAttendingEvent() from FollowersActivity to PostAdapter, fetch the count of followers in the adapter and then pass that count to the FollowersActivity through Intent in case you do not want to re fetch data.
PostAdapter -------> FollowersActivity
(count required here) (fetching here)
PostAdapter -------> FollowersActivity
(fetch count here) (pass data here through Intent of refetch it)
Please tell me if didn't understood the problem correctly i might come up with a better solution

How can i count a query / dataSnapshot? [duplicate]

This question already has answers here:
Default FirebaseApp is not initialized
(34 answers)
Closed 3 years ago.
I want to show the number of active users in my StartActivity. The users are divided into two groups: players and spectators. I tried it in my database with a Boolean value. How can I show / count the users?
Database:
Firebase Pic
StartActivity:
XML Pic
Here is my StartAytivity.class code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_start);
Button run = findViewById(R.id.button2);
run.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(StartActivity.this, MainActivity.class);
startActivity(intent);
}
});
FirebaseApp.initializeApp(this);
watcher = findViewById(R.id.textView3);
player = findViewById(R.id.textView4);
onlineCount();
}
Here is my OnlineCount code:
public void onlineCount(){
//watcher
refwatcher = FirebaseDatabase.getInstance()
.getReference("online_list")
.child("watcher")
.child(Objects.requireNonNull(FirebaseAuth.getInstance().getCurrentUser()).getUid()).child("online");
Query query = refwatcher.orderByChild("online").equalTo(true);
refwatcher.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
wcount = (int) dataSnapshot.getChildrenCount();
watcher.setText(getString(wcount) + getText(R.string._29_349_watchers_online));
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
//player
DatabaseReference refplayer = FirebaseDatabase.getInstance().getReference("online_list").child("player");
refplayer.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
player.setText("1" + getText(R.string._230_player_online));
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
Here is my debug code:
Caused by: java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203)
at com.bbinktattoo.nerve.StartActivity.onlineCount(StartActivity.java:65)
at com.bbinktattoo.nerve.StartActivity.onCreate(StartActivity.java:57)
at android.app.Activity.performCreate(Activity.java:7326)
at android.app.Activity.performCreate(Activity.java:7317)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
Your issue has nothing to do with the problem your question implies. You want to know how to count your database entries. Every element in firebase is a node and can have n children and has exactly 1 parent. The relation ship between a node and its parent is 1:1 while the relation ship between the node and its children is 1:n.
So if you want to count the amount of elements you have to call the getChildren() Method on the parent node, which will return n references to the n nodes.
However, it seems like you're not initializing the Firebase SDK as supposed to. Make sure you read and understand the related docs
https://firebase.google.com/docs/android/setup
I would guess that you have not set the correct configuration parameters
Your issue is not the counting itself but Firebase seems improperly setup in your app. Make sure to follow the official guide step by step. Also check Logcat for errors and warnings from Firebase, usually there is something useful.

Android studio value increment in Firebase

Can anyone teach me how to update my Firebase value when I click on my Android Studio App? There is no need to retrieve and display the data. Just an incremental value in my Realtime Database. For example, the Firebase counter value is 0 now, how I can increase the counter value in Firebase when I click on a button? I have tried using the code below, but it is not working.
import com.firebase.client.Firebase;
public class Voting extends AppCompatActivity {
private Button msendData;
int counter;
private Firebase mRef;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_voting);
Firebase.setAndroidContext(this);
mRef = new Firebase("https://lollol.firebaseio.com/");
msendData = (Button) findViewById(R.id.votethis);
msendData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Firebase mRefChild = mRef.child("Booth A");
mRefChild.setValue(counter++);
}
Edit: 20222608
Actually, there is a really simple solution nowadays in which we can increment a field in the Realtime Database which is:
scoreRef.setValue(ServerValue.increment(1));
And to decrement a value, simply pass a negative number:
scoreRef.setValue(ServerValue.increment(-1));
In order to increment a value in a Firebase database, first of all, you need to retrieve that value. There is no way to increment a value without knowing it. To achieve this, I definitely recommend you to use Firebase Transaction.
Let's take an example. Let's assume we want to increment a counter. In order to achieve this, please use the following code to set the default value of the counter.
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child("score").setValue(1);
Assuming that the score field is of type Integer, to use transactions, please use the following method:
public static void setScore(String operation) {
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference scoreRef = rootRef.child("score");
scoreRef.runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
Integer score = mutableData.getValue(Integer.class);
if (score == null) {
return Transaction.success(mutableData);
}
if (operation.equals("increaseScore")) {
mutableData.setValue(score + 1);
} else if (operation.equals("decreaseScore")){
mutableData.setValue(score - 1);
}
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {}
});
}
Using transactions, you will avoid inconsistent results if users are trying to increase/decrease the score at the same time. So as a conclusion, call this method accordingly to your increase/decrease operation.
If you want to read the score, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference scoreRef = rootRef.child("score");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Integer score = dataSnapshot.getValue(Integer.class);
Log.d("TAG", "score: " + score);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
scoreRef.addListenerForSingleValueEvent(eventListener);
Get the value from the database.
Make a simple while loop, with the number of increments you need. Declare the variable globally, not within the onCreate methods.
Set them back to the Database.
You don't need to retrieve the value if you use ServerValue.increment(). Recently, It landed on Flutter in version firebase_database 4.1.
The way you can use is:
mRefChild.set(ServerValue.increment(1));

Categories

Resources