I am currently trying to figure out why my Android application is loading information incorrectly into Firebase. The application is posting the information outside of it's location. This is where the information should be:
DriversInformation
-UE7cSOf5Thbum6OwEmg9seAPD463
rates: "0"
But instead, "rates" loads outside like so:
DriversInformation
-UE7cSOf5Thbum6OwEmg9seAPD463
-rates: "0"
In my code, I defined my reference as
driverInformationRef = database.getReference(Common.user_driver_tbl);
Common.user_driver_tbl is a global variable set as
public static final String user_driver_tbl = "DriversInformation";
When I post to Firebase, I am using this code
double finalAverage = averageStars/count;
DecimalFormat df = new DecimalFormat("#.#");
String valueUpdate = df.format(finalAverage);
Map<String,Object> driverUpdateRate = new HashMap<>();
driverUpdateRate.put("rates",valueUpdate);
driverInformationRef.child(Common.driverId)
.updateChildren(driverUpdateRate)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
alertDialog.dismiss();
Toast.makeText(RateActivity.this,"Thank you for your feedback",Toast.LENGTH_SHORT).show();
finish();
}
});
Why is driversInformationRef.child(Common.driverId) not accessing/posting to the correct child?
EDIT: Okay I am genuinely confused. After many recompiling, the rating system started to work. I added this line of code:
Log.d("FINALPROOF", String.valueOf(Common.driverId));
Why does this line of code make such a difference? Does this initilize the value in some way?
Related
This question already has answers here:
getContactsFromFirebase() method return an empty list
(1 answer)
Setting Singleton property value in Firebase Listener
(3 answers)
Closed last year.
I'm currently working with Firebase Realtime Database. I'm trying to read the data once when a certain method in my program gets called.
This is a project for a Discord bot. (https://github.com/DV8FromTheWorld/JDA)
The data is being read, however the execution order is wrong. I make the call to get the data but the program continues even-though the methods haven't been called yet properly.
To showcase my error I will include the code. Within the code I do printlines to illustrate what happens (or the order everything gets executed in).
I have attempted to work with Threads to fix this but I haven't managed to get it to work.
The code:
public class userLogs extends ListenerAdapter {
private FirebaseDatabase db;
private JDA jda;
private Stack<offense> allOffenses = new Stack<>();
public userLogs(FirebaseDatabase db, JDA jda){
this.db = db;
this.jda = jda;
}
#Override
public void onSlashCommand(SlashCommandEvent event)
{
if (!event.getName().equals("logs")) return; // make sure we handle the right command
this.allOffenses = new Stack<>();
// Selected user you want the logs from
String userID = event.getOption("user").getAsUser().getId();
new Thread(() -> {
/** GET ALL MUTES*/
db.getReference("Mutes").addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println("I am now getting all logs from the database.");
for(DataSnapshot ds : dataSnapshot.getChildren()){
String offenderID = ds.child("offenderID").getValue(String.class);
if(offenderID.equals(userID)) {
// Get moderator
String modID = ds.child("moderatorID").getValue(String.class);
User moderator = jda.getUserById(modID);
// Get reason
String reason = ds.child("reason").getValue(String.class);
Duration duration = Duration.ofSeconds(ds.child("duration").getValue(Long.class));
saveOffense(new offense("Mute", moderator.getAsTag(), reason, duration));
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}).start();
System.out.println("I just got out of the Thread. The stack size is: " + allOffenses.size());
// Create embed
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("Logs for user: " + jda.getUserById(userID).getAsTag());
StringBuilder sb = new StringBuilder();
for(int i = 0; i < allOffenses.size(); i++){
sb.append("Type: \n").append(allOffenses.get(i).getOffenseName());
sb.append("Moderator: \n" + allOffenses.get(i).getModerator());
sb.append("Reason: \n" + allOffenses.get(i).getReason());
Duration dur = allOffenses.get(i).getDuration();
if(dur != Duration.ZERO){
sb.append("Duration: \n" + dur);
}
}
eb.setDescription(sb.toString());
event.getChannel().sendMessageEmbeds(eb.build()).queue();
}
void saveOffense(offense off){
System.out.println("I just got in the method where I put a found offense into the stack.");
this.allOffenses.push(off);
}
}
This outputs the following whenever the method gets called: (There are 3 offenses logged so that is correct)
As you can see it exists the thread before it executes the code within it. I'm very confused about this and have spent the past 5+ hours trying to fix this.
I hope that I've explained the issue correctly. Thank you all very much for your help!
I've added refer coin system to my app in which if you refer it to someone you get 100 coins & the person refers code you were using get's the same. Bu the issue is when I run the app and use the referral code coins keep on increasing unless the app crashes. Coins should be added 100 in both accounts but they go from 0 to 24000 or more unless the app crashes.
The following code is :
reference
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
ProfileModel model = snapshot.child(oppositeUID).getValue(ProfileModel.class);
ProfileModel myModel = snapshot.child(user.getUid()).getValue(ProfileModel.class);
int coins = model.getCoins();
int updatedCoins = coins + 100;
int myCoins = myModel.getCoins();
int myUpdate = myCoins + 100;
HashMap<String, Object> map = new HashMap<>();
map.put("coins", updatedCoins);
HashMap<String, Object> myMap = new HashMap<>();
myMap.put("coins", myUpdate);
reference.child(oppositeUID).updateChildren(map);
reference.child(user.getUid()).updateChildren(myMap)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
dialog.dismiss();
Toast.makeText(InviteActivity.this, "Congrats", Toast.LENGTH_SHORT).show();
}
});
}
The problem in your code lies in the fact that you are using addValueEventListener. This means that you are listening for changes in real-time. Every time something changes in your database, the listener fires. Since you are listening to the same location you are performing the updates, the listener fires over and over again. What you need is addListenerForSingleValueEvent, to get the data exactly once.
To solve this, simply change the call to:
addValueEventListener()
To:
addListenerForSingleValueEvent()
And your code will work perfectly fine.
I'm trying to access a certain value within the last added Firebase node. In my database I have a set of Clients, which through my app, can be added to. Inside a client there's a piece of information titled 'clientName'. I would like to get this value.
Once I get the value, I'm trying to give a toast message showing that value.
Here is my code inside the onClick method of my button. I'm not sure why it's not working. If you know of another way I could do this or a way to fix my current code I'd really appreciate it!
Thanks in advance guys!
my_button[bt].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (my_button[Index].getId() == ((ImageButton) v).getId()) {
String bla = (String) getIntent().getExtras().get("id");
String address = "https://console.firebase.google.com/project/cssecond-92a2d/database/data/clients/" +bla+"/clientName";
Firebase ref = new Firebase(address);
ref.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(com.firebase.client.DataSnapshot dataSnapshot) {
String value = (String) dataSnapshot.getValue();
Toast.makeText(HomePageNews.this,"In your hands you have: "+ value ,Toast.LENGTH_LONG).show();
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
}
});
Everything looks fine in your code. The problem is this line of code:
String bla = (String) getIntent().getExtras().get("id");
The id that is returning from that intent is null, so your reference is also null. In order to fix this, you need to change the code to get the correct value from the intent that is coming from your previous activity and than it should work.
I have an android app that is retrieving data from a mysql db via php.
It works fine, but i have a (simple) variable problem.
I want to create a variable inside MainActivity class.
Then inside MainActiviy class i have onCreate method - and inside that I have some json stuff that retrieves my data from mysql.
I now want to assign some mysql value to the variable i created in MainActivity class (it is assigned inside onResponse method from the json stuff), and then I simply want to use that variable and write it out on a textview, and I will do that in the bottom of the onCreate method.
But for some reason, it "forgets" the value I assigned to the variable, when I have to use it outside the onResponse method.
(if i set the textview text inside the onResponse method, it works fine).
public class MainActivity extends ActionBarActivity {
// I create the variable here
String someString;
TextView text;
RequestQueue reqq;
String showUrl = "http://www.someurl.com/get_data.php";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.textid);
reqq = Volley.newRequestQueue(getApplicationContext());
JsonObjectRequest jsonob = new JsonObjectRequest(Request.Method.POST,
showUrl, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray dataAr = response.getJSONArray("json_data");
for (int i = 0; i < dataAr.length(); i++) {
JSONObject dat = dataAr.getJSONObject(i);
// Here I want to assign some data from my mysql db to the variable
someString = dat.getString("aar");
// If I set the the textview to display value of someString HERE, it works!
// text.setText(someString);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println(error.getMessage());
}
});
reqq.add(jsonob);
// HERE i want to display the value of the variable in the textview!
// - but it doesnt "remember" the value
text.setText(someString);
}
}
If I use static keyword on the someString variable, it remembers the value, but only the SECOND time i open the app!
I'm very new at this, and have tried google, and tried some stuff with a singleton class, but I just don't seem to understand this!
I would love it, if someone could link me some information to help me get this, AND give an example of how my code should be, so it will work!
THANKS! :D
This behavior is due to the fact that
text.setText(someString);
is executed immediately in the onCreate method, & by immediately I mean that it does not wait for any response from the Volley request (the Volley request that you set up before). In other words, you need to wait till you get a response before you set the text on to your TextView.
That's why it successfully sets your TextView's text from within the onResponse method.
So I've debugged my program and have found that the part of my program is updating, whilst another isn't.
I have a method:
public void storeApplication(String name, String item){
Application app = new Application(name, item);
peopleAttending.add(app);
}
The debugger reports that an object is contained in the LinkedList (peopleAttending).
In another method:
public void populateListView() {
int noOfPeopleAttending = peopleAttending.size();
String noPeopleAttending = String.valueOf(noOfPeopleAttending);
Toast.makeText(GuestsAttending.this, noPeopleAttending, Toast.LENGTH_SHORT).show();
}
This method can be called after the previous one and states that there isn't an object within the LinkedList.
I've checked the object references just to make sure that they are pointing at the same reference and they are.
Any help would be greatly appreciated.
EDIT: Entire Class:
public class GuestsAttending extends Activity {
private LinkedList<Application> peopleAttending = new LinkedList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_guests_attending);
populateListView();
}
public void storeApplication(String name, String item){
Application app = new Application(name, item);
peopleAttending.add(app);
}
public void populateListView() {
// GuestsAdapter adapter = new GuestsAdapter(this, peopleAttending);
// ListView listView = (ListView) findViewById(R.id.listView);
// listView.setAdapter(adapter);
peopleAttending.size();
int noOfPeopleAttending = peopleAttending.size();
String noPeopleAttending = String.valueOf(noOfPeopleAttending);
Toast.makeText(GuestsAttending.this, noPeopleAttending, Toast.LENGTH_SHORT).show();
}
Second Edit:
Java Booking Screen Method:
public void saveBookingInfo(View view) {
GuestsAttending sendApplication = new GuestsAttending();
EditText applicantNameText = (EditText) findViewById(R.id.applicantNameTextField);
EditText itemToBurnText = (EditText) findViewById(R.id.itemToBurnTextField);
String appName = applicantNameText.getText().toString();
String appItemToBurn = itemToBurnText.getText().toString();
if (appItemToBurn.isEmpty() || appName.isEmpty()) {
Toast.makeText(BookingScreen.this, "Please fill in all fields.", Toast.LENGTH_SHORT).show();
}
else {
sendApplication.storeApplication(appName, appItemToBurn);
}
}
GuestsAttending Java Class: -- See Above.
Useful hint: It's really popular to set type of List as a List<> interface from java.util package instead of LinkedList<> itself.
Anyway, i am pretty sure that storeApplication method is not automatically triggered before onCreate method ran by Activity framework. Maybe your debugger is stopoing on it in different order (because of using threads or smth), but you should to log some invoke. Try to find it out.
I've found out what the problem is:
When I submit the booking information, it runs all the necessary methods. However, when the "storeApplication()" method has finished executing, the ArrayList 'empties' all the objects out.
I only noticed this when I used breakpoint and tried running the method twice, on the second time I entered booking details, the ArrayList stated it was empty.
I'm going to see if I can try and store the ArrayList in a more secure place.