【问题标题】:Getting Calendar from firebase in Android在 Android 中从 firebase 获取日历
【发布时间】:2020-06-17 06:42:38
【问题描述】:

我正在构建一个日历应用程序,但我无法让后端正常工作。 我可以保存/删除和编辑我的事件,但是当用户点击日历时我无法显示它们。用户可以在屏幕上进行更改时查看他们保存的数据,但是一旦他们重新启动应用程序或单击其他视图,一切都消失了。我检查了我的列表内容,详情总是显示为空。

public class CalendarViewWithNotesActivitySDK21_v2 extends Fragment {

private final static int CREATE_EVENT_REQUEST_CODE = 100;

private String[] mShortMonths;
private CalendarView mCalendarView;
private CalendarDialog mCalendarDialog;

private List<CalenderEventModel> mEventList = new ArrayList<>();

private static Context context = null;

public static Intent makeIntent(Context context) {
    return new Intent(context, CalendarViewWithNotesActivitySDK21_v2.class);
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    context = getActivity();
    setHasOptionsMenu(true);
    View v = inflater.inflate(R.layout.activity_calendar_view_with_notes_sdk_21, container, false);

    //getFirebaseData();

    //mShortMonths = new DateFormatSymbols().getShortMonths();

    initializeUI(v);

    return v;
}

private void getFirebaseData() {
    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
    assert user != null;
    final String uid = user.getUid();
    final FirebaseDatabase db = FirebaseDatabase.getInstance();
    final DatabaseReference ref = db.getReference("Calendar Events").child(uid);

    ref.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            mEventList.clear();
            for(DataSnapshot ds : dataSnapshot.getChildren()) {
                String id = ds.getKey();
                String title = ds.child("title").getValue(String.class);
                Calendar date = ds.child("date").getValue();
                int color = ds.child("color").getValue(Integer.class);
                boolean complete = ds.child("completed").getValue(boolean.class);

                CalenderEventModel model = new CalenderEventModel(id,title,date,color,complete);
                mEventList.add(model);

                //mEventList.add(ds.getValue(CalenderEventModel.class));
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });

}

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

    getFirebaseData();

    mShortMonths = new DateFormatSymbols().getShortMonths();

    //initializeUI();
}

这就是我保存到 firebase 的方式

 private void save() {

    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
    assert user != null;
    final String uid = user.getUid();
    final FirebaseDatabase database = FirebaseDatabase.getInstance();
    final DatabaseReference ref = database.getReference("Calendar Events").child(uid);
    String key = ref.push().getKey();

    int action = mOriginalEvent != null ? ACTION_EDIT : ACTION_CREATE;
    String id = mOriginalEvent != null ? mOriginalEvent.getID() : key;
    String rawTitle = mTitleView.getText().toString().trim();

    if(mOriginalEvent == null) {
        mOriginalEvent = new CalenderEventModel(
                id,
                rawTitle.isEmpty() ? null : rawTitle,
                mCalendar,
                mColor,
                mIsCompleteCheckBox.isChecked()
        );
        Map<String, Object> childUpdate = new HashMap<>();
        childUpdate.put(key, mOriginalEvent.toFirebaseObject());
        ref.updateChildren(childUpdate, new DatabaseReference.CompletionListener() {
            @Override
            public void onComplete(@Nullable DatabaseError databaseError, @NonNull DatabaseReference databaseReference) {
                if (databaseError == null) {
                    return;
                }
            }
        });
    } else {
        mOriginalEvent.setmTitle(rawTitle.isEmpty() ? null : rawTitle);
        mOriginalEvent.setmDate(mCalendar);
        mOriginalEvent.setmColor(mColor);
        mOriginalEvent.setCompleted(mIsCompleteCheckBox.isChecked());
        ref.child(mOriginalEvent.getID()).setValue(mOriginalEvent);
    }

    setResult(RESULT_OK, new Intent()
            .putExtra(INTENT_EXTRA_ACTION, action)
            .putExtra(INTENT_EXTRA_EVENT, mOriginalEvent));
    finish();

    if (action == ACTION_CREATE)
        overridePendingTransition(R.anim.stay, R.anim.slide_out_down);

}

这是我的事件模式类

public class CalenderEventModel implements Parcelable {

private String mID;
private String mTitle;
private Calendar mDate;
private int mColor;
private boolean isCompleted;

public CalenderEventModel() {

}

public CalenderEventModel(String id, String title, Calendar date, int color, boolean isCompleted) {
    mID = id;
    mTitle = title;
    mDate = date;
    mColor = color;
    this.isCompleted = isCompleted;
}

public void setmID(String mID) {
    this.mID = mID;
}

public void setmTitle(String mTitle) {
    this.mTitle = mTitle;
}

public void setmDate(Calendar mDate) {
    this.mDate = mDate;
}

public void setmColor(int mColor) {
    this.mColor = mColor;
}

public void setCompleted(boolean completed) {
    isCompleted = completed;
}

public String getID() {
    return mID;
}

public String getTitle() {
    return mTitle;
}

public Calendar getDate() {
    return mDate;
}

public int getColor() {
    return mColor;
}

public boolean isCompleted() {
    return isCompleted;
}

public Map<String, Object> toFirebaseObject() {
    HashMap<String, Object> event = new HashMap<>();
    event.put("mid", mID);
    event.put("title", mTitle);
    event.put("date", mDate);
    event.put("color", mColor);
    event.put("completed", isCompleted);

    return event;
}

protected CalenderEventModel(Parcel in) {
    mID = in.readString();
    mTitle = in.readString();
    mColor = in.readInt();
    mDate = (Calendar) in.readSerializable();
    isCompleted = in.readByte() != 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(mID);
    dest.writeString(mTitle);
    dest.writeInt(mColor);
    dest.writeSerializable(mDate);
    dest.writeByte((byte) (isCompleted ? 1 : 0));
}

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

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

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

}

在获取firebase数据的方法中,我尝试将数据一一获取,如未注释掉的语句中所示,但我遇到了这个错误

java.lang.ClassCastException: java.util.HashMap cannot be cast to java.util.Calendar
    at com.example.serenity.CalendarViewWithNotesActivitySDK21_v2$1.onDataChange(CalendarViewWithNotesActivitySDK21_v2.java:91)
    at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@19.3.0:75)
    at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@19.3.0:63)
    at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@19.3.0:55)
    at android.os.Handler.handleCallback(Handler.java:907)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:223)
    at android.app.ActivityThread.main(ActivityThread.java:7478)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:549)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:941)

【问题讨论】:

    标签: java android firebase firebase-realtime-database


    【解决方案1】:

    您将收到以下异常:

    java.lang.ClassCastException: java.util.HashMap cannot be cast to java.util.Calendar
    

    因为您试图将 HashMap 类型的对象转换为 Calendar 类型的对象。这在Java中实际上是不可能的,因为它们之间没有继承关系。正如我在错误消息中看到的,您正尝试在 onDataChange() 方法中进行该转换。所以DataSnapshot 对象实际上包含一个HashMap 而不是 一个Calendar 对象。除此之外,Firebase 实时数据库中的 the Calendar is not a supported data-type

    要解决这个问题,请尝试通过迭代其元素来从 HashMap 对象中获取数据。此外,将mDate 属性的类型更改为CalenderEventModel 类中的HashMap 和not 日历类型。

    【讨论】:

    • 对不起,如果我将其更改为 Hashmap 而不是日历,我不确定它是如何工作的,因为我需要使用日历类中的方法来设置事件的时间和日期
    • 我明白这一点,但是您无法将日历对象添加到数据库中,因此您无法以这种方式取回它。如果您需要存储日期,您可以存储为 ServerValue.TIMESTAMP 或简单地存储为 Long 值,例如 here。最后,您可以简单地转换为 Calendar 对象。
    • 你一直在尝试,但我似乎无法得到它.. 你可以通过代码告诉我吗?
    • Stack Overflow 不是代码编写服务。您应该根据答案中的信息自行尝试,如果出现其他问题,请提出另一个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-18
    • 2018-06-25
    • 1970-01-01
    相关资源
    最近更新 更多