Can I retrieve two documents from the database in

2019-08-27 22:15发布

I'm writing an app in Android Studio. It connects to Firebase Firestore.

The data is structured like this (I've removed the irrelevant bits, for clarity):

Boxes
   - box1
      - grid_id
      - table_id
   -box2
      - grid_id
      - table_id
Grids
    - grid1
    - grid2
Tables
   - table1
   - table2

So, each time I retrieve a box, I also need to retrieve the corresponding Grid and Table.

In my Activity, I have the following:

public class BoxViewActivity {

   String box_id;
   Box box;
   FirebaseFirestore databaseRef;
   BoxFragment boxFragment;
   GridFragment gridFragment;
   TableFragment tableFragment;
   FragmentManager fragmentManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_edit_box);
        fragmentManager = getSupportFragmentManager();
        boxFragment = fragmentManager.findFragmentById(R.id.fragment_box);

        // Retrieve Box from database and set it up
        Intent intent = getIntent();
        box_id = intent.getStringExtra("BoxId");
        box = new Box();

        databaseRef = FirebaseFirestore.getInstance();

        boxDocRef = databaseRef.collection("boxes").document(box_id);
        boxDocRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                if (task.isSuccessful()) {
                    DocumentSnapshot document = task.getResult();
                    if (document.exists()) {
                        // Set up Box
                        box = document.toObject(Box.Class);
                        if (box != null) {
                            // Set up some box views
                        }
                        // Get grid/table key
                        setUpGrid(box.getGridId());
                        setUpTable(box.getTableId());
                    }
                }
            }
        });
    }

    private void setUpGrid(String gridId) {

        DocumentReference gridRef = databaseRef.collection("grids").document(gridId);

        gridRef.addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {

            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                if (task.isSuccessful()) {
                    DocumentSnapshot document = task.getResult();
                    if (document.exists()) {
                        // Retrieve Grid
                        Grid grid= document.toObject(Grid);
                        if (grid != null) {
                            boxFragment.setGrid(grid);
                        }
                    }
                }
            }
        });
    }

    private void setUpTable(String tableId) {
        if(tableId == null) return;

        DocumentReference tableRef = databaseRef.collection("tables").document(tableId);

        tableRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {

            @Override
            public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                if (task.isSuccessful()) {
                    DocumentSnapshot document = task.getResult();
                    if (document.exists()) {
                        Table table = document.toObject(Table.Class);
                        if (table != null) {
                            boxFragment.setTable(table);
                        }
                    }
            }
        });
    }

}

The problem I'm having is that the app seems to 'freeze' and then restart when I hit this activity. The screen goes blank and unresponsive, and then the app restarts. Android Studio isn't throwing any errors, and the debug console has nothing. I suspect it's because I'm retrieving the grid and table simultaneously - would that slow it down? If so, what's a better way to do it? Or have I missed something else?

1条回答
一夜七次
2楼-- · 2019-08-27 22:33

To solve this, I suggest you add a Grid and a Table object within a Box object. In this way you'll be able to a use a single listener instead of three. So your code should look like this:

boxDocRef = databaseRef.collection("boxes").document(box_id);
boxDocRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DocumentSnapshot> task) {
        if (task.isSuccessful()) {
            DocumentSnapshot document = task.getResult();
            FragmentManager fragmentManager = getSupportFragmentManager();
            BoxFragment boxFragment = fragmentManager.findFragmentById(R.id.fragment_box);
            if (document.exists()) {
                // Set up Box
                box = document.toObject(Box.Class);
                if (box != null) {
                    // Set up some box views
                    // Get grid/table key
                    Grid grid = box.getGrid();
                    boxFragment.setGrid(grid);
                    Table table = box.getTable();
                    boxFragment.setTable(table);
                }
            }
        }
    }
});

And remove the declaration of your FragmentManager and BoxFragment. Both should only be present inside the onComplete() method.

查看更多
登录 后发表回答