-1

It says that my getOutletId() is null references and i already declared, i think. So basically this is a booking step 4. For the first step, user need to choose outlet from firestore and choose which branch and i've already include to setOutlet id. Then the 2nd step will show the staff. All of the information i get it from firestore except for Id, i do it manually. Can someone help me with this please.

This is where i set the outlet id in Booking Step 1 fragment

private void loadBranchOfCity(String cityName) {
        dialog.show();

        Common.city = cityName;

        branchRef = FirebaseFirestore.getInstance()
                .collection("AllPlace")
                .document(cityName)
                .collection("Branch");

        branchRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                List<Outlet> list = new ArrayList<>();
                if (task.isSuccessful())
                {
                    for(QueryDocumentSnapshot documentSnapshot:task.getResult())
                    {
                        Outlet outlet = documentSnapshot.toObject(Outlet.class);
                        outlet.setOutletId(documentSnapshot.getId());
                        list.add(outlet);
                    }
                    iBranchLoadListener.onBranchLoadSuccess(list);
                }
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                iBranchLoadListener.onBranchLoadFailed(e.getMessage());
            }
        });
    }

Here is my booking activity where outletId is started showing

@OnClick(R.id.btn_next_step)
    void nextClick(){
        if (Common.step < 3 || Common.step == 0)
        {
            Common.step++; //increase
            if (Common.step == 1) //After choose outlet
            {
                if(Common.currentOutlet != null)
                    loadStaffByOutlet(Common.currentOutlet.getOutletId());
            }
            else if(Common.step == 2) //pick time slot
            {
                if(Common.currentStaff != null)
                    loadTimeSlotOfStaff(Common.currentStaff.getStaffId());
            }
            else if(Common.step == 3) //Confirm
            {
                    if(Common.currentTimeSlot != -1)
                    confirmBooking();
            }
            viewPager.setCurrentItem(Common.step);
        }
    }

    private void confirmBooking() {
        //Send broadcast to fragment step four
        Intent intent = new Intent (Common.KEY_CONFIRM_BOOKING);
        localBroadcastManager.sendBroadcast(intent);
    }

    private void loadTimeSlotOfStaff(String staffId) {
        //Send local broadcast to fragment step 3
        Intent intent = new Intent (Common.KEY_DISPLAY_TIME_SLOT);
        localBroadcastManager.sendBroadcast(intent);
    }

    private void loadStaffByOutlet(String outletId) {
        dialog.show();

        //Select all staff of Outlet
        // /AllPlace/Melaka/Branch/RCgub6eOcf2c0s06Soyb/Staff
        if (!TextUtils.isEmpty(Common.city))
        {
            staffRef = FirebaseFirestore.getInstance()
                    .collection("AllPlace")
                    .document(Common.city)
                    .collection("Branch")
                    .document(outletId)
                    .collection("Staff");

            staffRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    ArrayList<Staff> staffs = new ArrayList<>();
                    for(QueryDocumentSnapshot staffsnapshot:task.getResult())
                    {
                        Staff staff = staffsnapshot.toObject(Staff.class);
                        staff.setPassword(""); //Remove password because this is client app
                        staff.setStaffId(staffsnapshot.getId());//get id of staff

                        staffs.add(staff);
                    }
                    //Send Broadcast to BookingStep2Fragment to load Recycler
                    Intent intent = new Intent(Common.KEY_STAFF_LOAD_DONE);
                    intent.putParcelableArrayListExtra(Common.KEY_STAFF_LOAD_DONE,staffs);
                    localBroadcastManager.sendBroadcast(intent);

                    dialog.dismiss();
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    dialog.dismiss();
                }
            });

        }
    }

Here is my logcat

Process: com.example.CarServiceBooking, PID: 12259 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.CarServiceBooking.Model.Outlet.getOutletId()' on a null object reference at com.example.CarServiceBooking.Fragment.BookingStep4Fragment$3$2.onSuccess(BookingStep4Fragment.java:216) at com.example.CarServiceBooking.Fragment.BookingStep4Fragment$3$2.onSuccess(BookingStep4Fragment.java:199) at com.google.android.gms.tasks.zzn.run(Unknown Source) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5254) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

This is my Common class

    public class Common {
        public static final String KEY_ENABLE_BUTTON_NEXT = "ENABLE_BUTTON_NEXT";
        public static final String KEY_OUTLET_STORE = "OUTLET_SAVE";
        public static final String KEY_STAFF_LOAD_DONE = "STAFF_LOAD_DONE";
        public static final String KEY_DISPLAY_TIME_SLOT = "DISPLAY_TIME_SLOT";
        public static final String KEY_STEP = "STEP" ;
        public static final String KEY_STAFF_SELECTED = "STAFF_SELECTED";
        public static final Object DISABLE_TAG = "DISABLE";
        public static final String KEY_TIME_SLOT = "TIME_SLOT";
        public static final String KEY_CONFIRM_BOOKING = "CONFIRM_BOOKING";
        public static final String IS_LOGIN = "IsLogin";
        public static final String EVENT_URI_CACHE = "URI_EVENT_SAVE";
        public static final String TITLE_KEY = "title";
        public static final String CONTENT_KEY = "content";
        private static final String LOGGED_KEY = "LOGGED";
        public static User currentUser;
        public static Outlet currentOutlet;
        public static Staff currentStaff;
        public static int step = 0; //init first step is 0
        public static String city = "";
        public static int currentTimeSlot = -1;
        public static final int TIME_SLOT_TOTAL = 9;
        public static Calendar bookingDate = Calendar.getInstance();
        public static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd_MM_yyyy"); //only use when need format key
        public static BookingInformation currentBooking;
        public static String currentBookingId = "";

This is my BookingStep4Fragment where the logcat says it is null references

private void addToUserBooking(final BookingInformation bookingInformation) {
        resetStaticData();
        getActivity().finish(); //close activity
        Toast.makeText(getContext(), "Success!", Toast.LENGTH_SHORT).show();

        //First, create new collection
        CollectionReference userBooking = FirebaseFirestore.getInstance()
                .collection("Users")
                .document(Common.currentUser.getPhone())
                .collection("Booking");

        //Check if exist document in this collection
        //Get Current Date
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE,0);
        calendar.set(Calendar.HOUR_OF_DAY,0);
        calendar.set(Calendar.MINUTE,0);

        Timestamp toDayTimeStamp = new Timestamp(calendar.getTime());

        userBooking
                .whereGreaterThanOrEqualTo("timestamp",toDayTimeStamp)
                .whereEqualTo("done",false)
                .limit(1) //only take 1
                .get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if(task.isSuccessful())
                        {
                            //set data
                            userBooking.document()
                                    .set(bookingInformation)
                                    .addOnSuccessListener(new OnSuccessListener<Void>() {
                                        @Override
                                        public void onSuccess(Void aVoid)
                                        {
                                            //Create Notification
                                            MyNotification myNotification = new MyNotification();
                                            myNotification.setUid(UUID.randomUUID().toString());
                                            myNotification.setTitle("New Booking ");
                                            myNotification.setContent("You have a new appointment for customer vehicle with "+Common.currentUser.getName());
                                            myNotification.setRead(false); // we will only filter notification with 'read' is false on staff app
                                            myNotification.setServerTimestamp(FieldValue.serverTimestamp());

                                            //Submit notification to 'Notifications' collection of Staff
                                            FirebaseFirestore.getInstance()
                                                    .collection("AllPlace")
                                                    .document(Common.city)
                                                    .collection("Branch")
                                                    .document(Common.currentOutlet.getOutletId())
                                                    .collection("Staff")
                                                    .document(Common.currentStaff.getStaffId())
                                                    .collection("Notifications") //if it not available, it will be create automatically
                                                    .document(myNotification.getUid()) //create unique key
                                                    .set(myNotification)
                                                    .addOnSuccessListener(new OnSuccessListener<Void>() {
                                                        @Override
                                                        public void onSuccess(Void aVoid) {
                                                            //First get Token base on staff id
                                                            FirebaseFirestore.getInstance()
                                                                    .collection("Tokens")
                                                                    .whereEqualTo("userPhone",Common.currentStaff.getUsername())
                                                                    .limit(1)
                                                                    .get()
                                                                    .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                                                                        @Override
                                                                        public void onComplete(@NonNull Task<QuerySnapshot> task) {
                                                                            if (task.isSuccessful() && task.getResult().size() > 0)
                                                                            {
                                                                                MyToken myToken = new MyToken();
                                                                                for (DocumentSnapshot tokenSnapShot : task.getResult())
                                                                                    myToken = tokenSnapShot.toObject(MyToken.class);

                                                                                //Create data to send
                                                                                FCMSendData sendRequest = new FCMSendData();
                                                                                Map<String,String> dataSend = new HashMap<>();
                                                                                dataSend.put(Common.TITLE_KEY, "New Booking");
                                                                                dataSend.put(Common.CONTENT_KEY,"You have new booking from user "+Common.currentUser.getName());

                                                                                sendRequest.setTo(myToken.getToken());
                                                                                sendRequest.setData(dataSend);

                                                                                compositeDisposable.add(ifcmApi.sendNotification(sendRequest)
                                                                                        .subscribeOn(Schedulers.io())
                                                                                        .observeOn(AndroidSchedulers.mainThread())
                                                                                        .subscribe(new Consumer<FCMResponse>() {
                                                                                            @Override
                                                                                            public void accept(FCMResponse fcmResponse) throws Exception {
                                                                                                dialog.dismiss();;

                                                                                                addToCalendar(Common.bookingDate,
                                                                                                        Common.convertTimeSlotToString(Common.currentTimeSlot));
                                                                                                resetStaticData();
                                                                                                getActivity().finish(); //Close activity
                                                                                                Toast.makeText(getContext(), "Success!", Toast.LENGTH_SHORT).show();
                                                                                            }
                                                                                        }, new Consumer<Throwable>() {
                                                                                            @Override
                                                                                            public void accept(Throwable throwable) throws Exception {
                                                                                                Log.d("NOTIFICATION_ERROR",throwable.getMessage());
                                                                                                addToCalendar(Common.bookingDate,
                                                                                                        Common.convertTimeSlotToString(Common.currentTimeSlot));
                                                                                                resetStaticData();
                                                                                                getActivity().finish(); //Close activity
                                                                                                Toast.makeText(getContext(), "Success!", Toast.LENGTH_SHORT).show();


                                                                                            }
                                                                                        }));

                                                                            }
                                                                        }
                                                                    });
                                                        }
                                                    });
                                        }
                                    })
                                    .addOnFailureListener(new OnFailureListener() {
                                        @Override
                                        public void onFailure(@NonNull Exception e) {
                                            Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
                                        }
                                    });
                        }
                        else
                        {
                            if(dialog.isShowing())
                                dialog.dismiss();

                            resetStaticData();
                            getActivity().finish(); //close activity
                            Toast.makeText(getContext(), "Success!", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
    }

This is my Outlet class

public class Outlet implements Parcelable {
    private String name,address,website, phone,openHours,outletId;

    public Outlet() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getWebsite() {
        return website;
    }

    public void setWebsite(String website) {
        this.website = website;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getOpenHours() {
        return openHours;
    }

    public void setOpenHours(String openHours) {
        this.openHours = openHours;
    }

    public String getOutletId() {
        return outletId;
    }

    public void setOutletId(String outletId) {
        this.outletId = outletId;
    }

    protected Outlet(Parcel in) {
        name = in.readString();
        address = in.readString();
        website = in.readString();
        phone = in.readString();
        openHours = in.readString();
        outletId = in.readString();
    }

    public static final Creator<Outlet> CREATOR = new Creator<Outlet>() {
        @Override
        public Outlet createFromParcel(Parcel in) {
            return new Outlet(in);
        }

        @Override
        public Outlet[] newArray(int size) {
            return new Outlet[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeString(address);
        dest.writeString(website);
        dest.writeString(phone);
        dest.writeString(openHours);
        dest.writeString(outletId);
    }
}
Shotnox
  • 1
  • 3

1 Answers1

0

Error at Common .You will get error in this lines.

    public static User currentUser;
    public static Outlet currentOutlet;
    public static Staff currentStaff;
    public static BookingInformation currentBooking;

because , you did not initialize. You should do like this;

  public static User currentUser = new User ();
    public static Outlet currentOutlet = new Outlet ();
    public static Staff currentStaff =  new Staff ();
    public static BookingInformation currentBooking = new BookingInformation();

may be you will get another error .I show above code, you didnot set any value for model.Only you get values form model .you should set data in model before get data from model.

ashok
  • 431
  • 5
  • 8
  • I've already set data in model in bookingstep1fragment. Here is my code for(QueryDocumentSnapshot documentSnapshot:task.getResult()) { Outlet outlet = documentSnapshot.toObject(Outlet.class); outlet.setOutletId(documentSnapshot.getId()); list.add(outlet); } – Shotnox Feb 04 '20 at 10:47
  • I think you have not set data for outletId, or may be if you are collect data from server and set it model ,that case you cant receive outletId from server ,so outletId null in model . – ashok Feb 04 '20 at 10:51
  • You debug below outlet.setOutletId(documentSnapshot.getId()); list.add(outlet) this line and check outlet data I think here not set any data for outletId. – ashok Feb 04 '20 at 10:53
  • i already edit the question. There i've set data for outletId – Shotnox Feb 04 '20 at 11:00
  • You not defined Common.currentOutlet = outlet ; any where inside addOnCompleteListener – ashok Feb 04 '20 at 11:06
  • where is it? which addOnCompleteListener? – Shotnox Feb 04 '20 at 11:23
  • inside loadBranchOfCity(String cityName); – ashok Feb 04 '20 at 11:24
  • i try to declare inside the for loop. but it still shows the same error – Shotnox Feb 04 '20 at 11:46
  • i follow the code from this video https://www.youtube.com/watch?v=G6z1uLPqRDY&list=PLaoF-xhnnrRUzve8vBXbPAhONMgTqHQ8i&index=6 and it's code doesnt have an error like mine. – Shotnox Feb 04 '20 at 11:51
  • I already include my booking activity and thats where the outletId start from – Shotnox Feb 04 '20 at 12:01
  • are You get data from server? – ashok Feb 04 '20 at 12:02
  • the rest are from the firestore, but for Id, i manually update – Shotnox Feb 04 '20 at 12:05
  • Can u help me ashok? – Shotnox Feb 04 '20 at 12:22
  • You do first in Outlet model private String name="test",address="test",website="test", phone="test",openHours="test",outletId="test"; and inside Common Outlet currentOutlet= new Outlet (); run and tell . – ashok Feb 04 '20 at 12:41
  • it shows E/RecyclerView: No adapter attached; skipping layout – Shotnox Feb 04 '20 at 13:08
  • You did not write full code or may be full code not shown in youtube video .thats why you missed some code. – ashok Feb 04 '20 at 13:15
  • do you hava signin method in your app? – ashok Feb 04 '20 at 13:17
  • if have not have then ,you change firebase data base permission. – ashok Feb 04 '20 at 13:18
  • its a full code sir. Yes i do have sign in method. google authentication – Shotnox Feb 04 '20 at 13:41