Search code examples
javaandroidparse-platformback4app

New to Parse Platform: Question on getting objectId of a relation


I have the following tables

  • Restaurants
  • Table
  • Reservation

I am creating a table availability search for a restaurant where the user inputs date and time. The result shows tables that are available AKA not already reserved at the selected date/time.

  1. I am checking the date/time for tables at a specific restaurant:
    • this objectID is passed from the previous activity (Restaurant profile)
ParseQuery<ParseObject> restaurant = ParseQuery.getQuery("Restaurants");
restaurant.get(objectID);
  1. I get the tables associated with the Restaurant from the Table table
ParseQuery<ParseObject> tableQuery = ParseQuery.getQuery("Table");
tableQuery.whereMatchesQuery("restaurant_id", restaurant);
  1. Then I get the reservations associated with those tables on the Reservation table and collect them in the reservationResults list
ParseQuery<ParseObject> reservations = ParseQuery.getQuery("Reservation");
reservations.whereMatchesQuery("table_id", tableQuery);
reservations.include("table_id");
List<ParseObject> reservationResults = reservations.find();
  1. From here I try to loop through the list of ParseObjects and do some calculations/checks on the reservation date/times. IF the date/time selected at the start clashes with any of the already made reservation date/times --> THEN I grab the table objectId of those that clash and add them to a 'List tableListToExclude'. This list is then used to check that certain tables aren't shown in a recyclerView if they are reserved for the selected time
for(int i = 0; i < reservationResults.size(); i++) {

    Date reservationDateTime = reservationResults.get(i).getDate("time");
    ParseObject reservation = reservationResults.get(i);
    ParseObject table = reservation.getParseObject("table_id");
    String tableId = table.getObjectId();
    Log.i(TAG, "|||||||||||TEST|||||||| ------> " + tableId);

    // calculates the two hour window of the reservation
    Calendar calRes = Calendar.getInstance();
    assert reservationDateTime != null;
    calRes.setTime(reservationDateTime);
    calRes.add(Calendar.HOUR_OF_DAY, 2);

    //sets the end time of two hour window
    Date reservationEndTime = calRes.getTime();

    // calculates two hours window of selected time
    Calendar calSelected = Calendar.getInstance();
    calSelected.setTime(combinedSelectedDate);
    calSelected.add(Calendar.HOUR_OF_DAY, 2);

    // sets the end time of the selected
    Date selectedEndTime = calSelected.getTime();

    //compares the selected date/time and it's 2 hour window against the Reservation table
    if((combinedSelectedDate.after(reservationDateTime) && combinedSelectedDate.before(reservationEndTime)) || (selectedEndTime.after(reservationDateTime) && selectedEndTime.before(reservationEndTime))) {
     Log.i(TAG, "||||||||||||TEST||||||||||||| ---------> Some dates fall in the 2 hour window");

           tableListToExclude.add(tableId);
           System.out.println(Arrays.asList(tableListToExclude));
    }
}

The error I get in the logcat:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.parse.ParseObject.getObjectId()' on a null object reference

I'm stuck here but I believe it's just from not totally understanding Parse and how to query relationships or pointers etc,... Do I need to create another query here? Or somehow get the ParseRelation and then that into a ParsObject and then get the objectId? I have tried a few different scenarios here but no luck, I think I am close but there's just something I'm not fully understanding or missing...

Also, any suggestions on a better approach to filter out my recyclerview items based on a date/time is welcome too!! If you need any more code or clarification just let me know. Thanks!


EDIT

Current version I have made tweaks to the queries at the start and also used findInBackground() instead of find():

//        ParseQuery<ParseObject> restaurant = ParseQuery.getQuery("Restaurants");
//        restaurant.get(objectID);

        ParseQuery<ParseObject> tableQuery = ParseQuery.getQuery("Table");
        tableQuery.whereEqualTo("restaurant_id", ParseObject.createWithoutData("Restaurants", objectID));

        ParseQuery<ParseObject> reservations = ParseQuery.getQuery("Reservation");
        reservations.whereMatchesQuery("table_id", tableQuery);
        reservations.include("table_id");

        reservations.findInBackground(new FindCallback<ParseObject>() {
            @Override
            public void done(List<ParseObject> reservationResults, ParseException e) {
                for(int i = 0; i < reservationResults.size(); i++) {
                    
                    Date reservationDateTime = reservationResults.get(i).getDate("time");

                    ParseObject reservation = reservationResults.get(i);
                    ParseObject table = reservation.getParseObject("table_id");
                    String tableId = table.getObjectId();

                    System.out.println(tableId);

                    // calculates the two hour window of the reservation
                    Calendar calRes = Calendar.getInstance();
                    assert reservationDateTime != null;
                    calRes.setTime(reservationDateTime);
                    calRes.add(Calendar.HOUR_OF_DAY, 2);

                    //sets the end time of two hour window
                    Date reservationEndTime = calRes.getTime();

                    // calculates two hours window of selected time
                    Calendar calSelected = Calendar.getInstance();
                    calSelected.setTime(combinedSelectedDate);
                    calSelected.add(Calendar.HOUR_OF_DAY, 2);

                    // sets the end time of the selected
                    Date selectedEndTime = calSelected.getTime();

                    //compares the selected date and time against the reservation times of the tables
                    if((combinedSelectedDate.after(reservationDateTime) && combinedSelectedDate.before(reservationEndTime)) || (selectedEndTime.after(reservationDateTime) && selectedEndTime.before(reservationEndTime))) {
                        Log.i(TAG, "||||||||||||TEST||||||||||||| ---------> Some dates fall in the 2 hour window");

                        tableListToExclude.add(tableId);
                        System.out.println(Arrays.asList(tableListToExclude));
                    }
                }
            }
        });

Solution

  • Try this for steps 1-3:

    ParseQuery<ParseObject> tableQuery = ParseQuery.getQuery("Table");
    tableQuery.whereEqualTo("restaurant_id", ParseObject.createWithoutData("Restaurants", objectID));
    
    ParseQuery<ParseObject> reservations = ParseQuery.getQuery("Reservation");
    reservations.whereMatchesQuery("table_id", tableQuery);
    reservations.include("table_id");
    List<ParseObject> reservationResults = reservations.find();
    

    Now step 4 should work. Note that you are using find function and it blocks the main thread. So it is recommended to use findInBackground for a better performance on your app.