Patricia
Patricia

Reputation: 95

How to execute success method in Firebase?

I'm developing an Android+Firebase app but since I'm new to both techlogies I'm having a problem regarding async calls and I haven't found the solution yet so hope you can help me.

I have the following snippet in my Activity's onCreate method:

final ArrayList<AssetLocation> assetsLocations = new ArrayList<>();
        DatabaseReference assetsLocationReference = database.getReference(FirebaseReferences.ASSETSLOCATION_REFERENCE);
        assetsLocationReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot snapshot) {
                ArrayList<String> assetsLocationSpinner = new ArrayList<String>();
                // Create an ArrayAdapter using the string array and a default spinner layout
                for (DataSnapshot postSnapshot : snapshot.getChildren()) {
                    //Getting the data from snapshot
                    AssetLocation assetsLocation = postSnapshot.getValue(AssetLocation.class);
                    assetsLocations.add(AssetLocation);
                }
            }

            @Override
            public void onCancelled(DatabaseError firebaseError) {
                System.out.println("The read failed: " + firebaseError.getMessage());
            }
        });

I also have a pretty similar call but instead of getting Locations, I'm getting Types.

After this code (inside the onCreate method as well), I'm calling setScreenInfo which is a function to fill both spinners (and do more stuff) with said data but since it is an async call, the spinners are blank when I execute it.

How can I execute setScreenInfo once the calls are made? I tried with .once()/.on() but it's not being recognised by Android Studio as a function.

Thanks for your help!

Upvotes: 0

Views: 553

Answers (3)

user6340995
user6340995

Reputation:

You can use thread:

thread = new Thread() {

    @Override
    public void run() {

        try {
            //background tasks

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    //UI tasks
                }
            });
        }
        catch (JSONException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
};
    thread.start();`

Or you can use Firebase Multi Query method. link: Only load layout when firebase calls are complete

Upvotes: 0

Alex Mamo
Alex Mamo

Reputation: 138834

Because of the asynchronously behaviour, you need to move the declaration of the assetsLocations ArrayList:

final ArrayList<AssetLocation> assetsLocations = new ArrayList<>();

inside the onDataChange() method, as assetsLocationSpinner ArrayList is. So remember, onDataChange is always called asynchronously. This means that the statement that adds objects of AssetLocation class to the list is executed before onDataChange has been called. That's why your list is empty outside that method.

For other approach, please visit this post and this post.

Hope ot helps.

Upvotes: 0

James Poag
James Poag

Reputation: 2380

After this code (inside the onCreate method as well), I'm calling setScreenInfo which is a function to fill both spinners (and do more stuff) with said data but since it is an async call, the spinners are blank when I execute it.

You aren't allowed to modify the UI from a background thread. Normally I would make a call to runOnUIThread, passing a new Runnable() and a final copy of the data I want to pass.

        final String myData = "updateData";

        ActivityName.this.runOnUiThread(new Runnable() {

            public void run() {
                // use myData to update UI
            }
        });

However, it seems like there's a migration to AsyncTask : Converting runOnUiThread to AsyncTask

I personally still use runOnUIThread. It's more explicit.

Upvotes: 1

Related Questions