它说我的getOutletId((是空引用,我想我已经声明了。 所以基本上这是一个预订步骤4。第一步,用户需要从Firestore中选择出口并选择哪个分支,我已经包含设置出口ID。然后第二步将显示工作人员。除了 Id 之外,我从 firestore 获得的所有信息都是手动完成的。 有人可以帮我解决这个问题吗?
这是我在预订步骤 1 片段中设置网点 ID 的地方
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());
}
});
}
这是我的预订活动,其中开始显示 outletId
@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();
}
});
}
}
这是我的日志猫
流程: com.example.carServiceBooking, PID: 12259 java.lang.NullPointerException:尝试调用虚拟方法 'java.lang.String com.example.CarServiceBooking.Model.Outlet.getOutletId((' on a null 对象引用 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(未知来源( 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(
这是我的普通类
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 = "";
这是我的BookingStep4Fragment,日志猫说它是空引用
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();
}
}
});
}
这是我的奥特莱斯类
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);
}
}
常见错误。您将在此行中出现错误。
public static User currentUser;
public static Outlet currentOutlet;
public static Staff currentStaff;
public static BookingInformation currentBooking;
因为 ,您没有初始化。你应该这样做;
public static User currentUser = new User ();
public static Outlet currentOutlet = new Outlet ();
public static Staff currentStaff = new Staff ();
public static BookingInformation currentBooking = new BookingInformation();
可能是你会得到另一个错误.我显示了上面的代码,您没有为模型设置任何值。只有您从模型中获取值,您应该在从模型中获取数据之前在模型中设置数据。