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!