当我尝试实现 Firebase 实时数据库后切换到片段时,Android 应用程序崩溃

问题描述 投票:0回答:1

我让它与 SQLite 数据库一起工作,但当我尝试切换到 Firebase 实时数据库时,它决定开始崩溃......我完全迷失了这个。一些帮助将不胜感激。

这是我的 Firebase 数据

注册用户 xJnXFIRYehWTXq4oKTOEdEXGY4D3 出生日期:“2024 年 5 月 7 日” 性别:“男” 手机:“2042322553”

日报 -Nztkpg1DjX9CvdYuH8b 每日ID: 0 信息:“3x 吉他” 每周:假

这是我的片段

package com.example.goalhero;

import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import static android.app.Activity.RESULT_OK;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;

import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class FragDailies extends Fragment {
    Button newDailyBtn;
    RecyclerView dailiesRecyclerView;
    RecyclerViewAdapterDailies adapter;
    final static int requestCodeForCreateNewDailyActivityCall = 2;
    ArrayList<DataDaily> dailies;
    private DatabaseReference dailiesDatabaseReference;
    private DailiesLifecycleObserver lifecycleObserver = new DailiesLifecycleObserver();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FirebaseDatabase database = FirebaseDatabase.getInstance();
        dailiesDatabaseReference = database.getReference("dailies");
        dailies = new ArrayList<>();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_dailies, container, false);
        dailiesRecyclerView = rootView.findViewById(R.id.dailiesRecyclerView);
        dailiesRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        adapter = new RecyclerViewAdapterDailies(getContext(), dailies);
        dailiesRecyclerView.setAdapter(adapter);
        return rootView;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        newDailyBtn = view.findViewById(R.id.launchCreateNewDailyActivityBtn);
        newDailyBtn.setOnClickListener(v -> {
            Intent intent = new Intent(getContext(), CreateNewDailyActivity.class);
            startActivityForResult(intent, requestCodeForCreateNewDailyActivityCall);
        });
        loadDailiesFromFirebase();
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == requestCodeForCreateNewDailyActivityCall && resultCode == RESULT_OK) {
            if (!data.getStringExtra("title").equals("")) {
                DataDaily curDaily = new DataDaily(data.getBooleanExtra("mon", true),
                        data.getBooleanExtra("tues", true),
                        data.getBooleanExtra("wed", true),
                        data.getBooleanExtra("thurs", true),
                        data.getBooleanExtra("fri", true),
                        data.getBooleanExtra("sat", true),
                        data.getBooleanExtra("sun", true), false,
                        data.getBooleanExtra("isEasy", true),
                        data.getStringExtra("title"),
                        data.getStringExtra("timeframe"),
                        data.getStringExtra("reps"));
                addDailyToFirebase(curDaily);
            }
        }
    }

    private void addDailyToFirebase(DataDaily daily) {
        dailiesDatabaseReference.push().setValue(daily)
                .addOnCompleteListener(task -> {
                    if (task.isSuccessful()) {
                        Toast.makeText(getContext(), "Daily added successfully", Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(getContext(), "Failed to add daily", Toast.LENGTH_LONG).show();
                    }
                });
    }

    private void loadDailiesFromFirebase() {
        dailiesDatabaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                dailies.clear();
                for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
                    DataDaily daily = postSnapshot.getValue(DataDaily.class);
                    if (daily != null) {
                        dailies.add(daily);
                    } else {
                        // Log the issue if daily is null
                        System.out.println("DataDaily is null for snapshot: " + postSnapshot.getKey());
                    }
                }
                adapter.setDailies(dailies);
                adapter.notifyDataSetChanged();
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Toast.makeText(getContext(), "Failed to load dailies: " + databaseError.getMessage(), Toast.LENGTH_LONG).show();
                // Log the error message
                System.out.println("DatabaseError: " + databaseError.getMessage());
            }
        });
    }


    public void addDaily(String title, String timeframe, String reps, boolean mon, boolean tues, boolean wed, boolean thurs, boolean fri, boolean sat, boolean sun, boolean isEasy, boolean isHard) {
        DataDaily daily = new DataDaily(mon, tues, wed, thurs, fri, sat, sun, false, isEasy, title, timeframe, reps);
        addDailyToFirebase(daily);
    }

    private class DailiesLifecycleObserver {
        public void onResumeFragment() {
            loadDailiesFromFirebase();
        }
    }
}

您可能还想查看 RecyclerViewAdapter

package com.example.goalhero;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
import java.util.Random;

public class RecyclerViewAdapterDailies extends RecyclerView.Adapter<RecyclerViewAdapterDailies.ViewHolder> {
    private ArrayList<DataDaily> dailies;
    private Context context;
    private DatabaseReference dailiesDatabaseReference;

    // Constructor
    public RecyclerViewAdapterDailies(Context context, ArrayList<DataDaily> dailies) {
        this.context = context;
        this.dailies = dailies;

        FirebaseDatabase database = FirebaseDatabase.getInstance();
        dailiesDatabaseReference = database.getReference("dailies");
    }

    // Set dailies data
    public void setDailies(ArrayList<DataDaily> dailies) {
        this.dailies = dailies;
        notifyDataSetChanged();
    }

    // ViewHolder class
    public class ViewHolder extends RecyclerView.ViewHolder {
        private CheckBox dailyListItemCB;
        private TextView dailyTextView;
        private ImageView deleteImage;
        private RelativeLayout parent;

        // Constructor
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            parent = itemView.findViewById(R.id.parent);
            dailyListItemCB = itemView.findViewById(R.id.list_itemCB);
            dailyTextView = itemView.findViewById(R.id.textView);
            deleteImage = itemView.findViewById(R.id.imageViewDeleteDaily);
        }
    }

    // onCreateViewHolder
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.dailies_list_item, parent, false);
        return new ViewHolder(view);
    }

    // onBindViewHolder
    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        // Narrows it down to just one daily
        final DataDaily currentDaily = dailies.get(position);

        // Bind data to views
        holder.dailyListItemCB.setText(currentDaily.getInfo());
        if (!currentDaily.timeFrame.equals("")) {
            holder.dailyTextView.setText(currentDaily.timeFrame);
        }

        holder.dailyListItemCB.setChecked(currentDaily.completedToday);

        holder.dailyListItemCB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                currentDaily.completedToday = isChecked;
                updateCompletionStatusInFirebase(currentDaily);

                // Notify the adapter about the item change
                notifyDataSetChanged();

                // Create an instance of the Random class
                Random random = new Random();
                // Generate a random number between 1 and 10
                int randomNumber = random.nextInt(10) + 1;

                // Check if the click count is 10
                if (randomNumber == 10) {
                    // Show the popup window
                    if (context instanceof ActivityMain) {
                        ((ActivityMain) context).showPopupWindow();
                    }
                }
            }
        });

        holder.deleteImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                deleteDailyFromFirebase(currentDaily);
            }
        });
    }

    // getItemCount
    @Override
    public int getItemCount() {
        return dailies.size();
    }

    // Helper methods to interact with Firebase
    private void updateCompletionStatusInFirebase(DataDaily daily) {
        dailiesDatabaseReference.child(daily.getDailyID()+"").setValue(daily)
                .addOnCompleteListener(task -> {
                    if (task.isSuccessful()) {
                        Toast.makeText(context, "Status updated successfully", Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(context, "Status update failed", Toast.LENGTH_SHORT).show();
                    }
                });
    }

    private void deleteDailyFromFirebase(DataDaily daily) {
        dailiesDatabaseReference.child(daily.getDailyID()+"").removeValue()
                .addOnCompleteListener(task -> {
                    if (task.isSuccessful()) {
                        dailies.remove(daily);
                        notifyDataSetChanged();
                        Toast.makeText(context, "Daily deleted successfully", Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(context, "Failed to delete daily", Toast.LENGTH_SHORT).show();
                    }
                });
    }
}

这是我认为导致应用程序停止工作的错误......

致命异常:主要 进程:com.example.goalhero,PID:29735 com.google.firebase.database.DatabaseException:com.example.goalhero.DataDaily 类未定义无参数构造函数。如果您使用 ProGuard,请确保这些构造函数没有被删除。 在 com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:578) 在 com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:571) 在 com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(CustomClassMapper.java:433) 在 com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:232) 在 com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:80) 在 com.google.firebase.database.DataSnapshot.getValue(DataSnapshot.java:202) 在 com.example.goalhero.FragDailies$1.onDataChange(FragDailies.java:102) 在 com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75) 在 com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63) 在 com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55) 在 android.os.Handler.handleCallback(Handler.java:938) 在 android.os.Handler.dispatchMessage(Handler.java:99) 在 android.os.Looper.loop(Looper.java:223) 在 android.app.ActivityThread.main(ActivityThread.java:7656) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

我完全迷失了,我刚刚开始使用 Firebase,所以我不知道......而且我是编程新手。

java android firebase firebase-realtime-database
1个回答
0
投票

调用

postSnapshot.getValue(DataDaily.class);
需要
DataDaily.java
类具有无参构造函数。

您可以通过将

public DataDaily(){}
添加到
DataDaily.java

来解决此问题

查看示例 Firebase 官方文档

© www.soinside.com 2019 - 2024. All rights reserved.