【问题标题】:RecyclerView crashes when I update data to Firestore当我将数据更新到 Firestore 时 RecyclerView 崩溃
【发布时间】:2023-01-27 03:17:19
【问题描述】:

我正在显示来自 Firebase Firestore 集合的数据,该应用程序运行良好,但当我将数据更新到来自其他设备的集合时(我有一个 Arduino,其传感器连接到执行 Python 脚本以将串行数据转换为 JSON 的 PC然后我更新 Firestore 集合上的数据,这些功能的所有后端都完美运行。我的问题是 Android 上的 Java。

我已经在这个论坛上搜索了解决方案,似乎有些东西不适用于 Adapter、RecyclerView 和“notifyDataSetChanged();”当前的解决方案都不适合我,或者我可能只是不知道如何在我的项目中实施它们。

这是我的模型

public class Monitor {
    String alias, placa, temp, acid;

    public Monitor(){}

    public Monitor(String alias, String placa, String temp, String acid) {
        this.alias = alias;
        this.placa = placa;
        this.temp = temp;
        this.acid = acid;
    }

    public String getAlias() {
        return alias;
    }

    public void setAlias(String alias) {
        this.alias = alias;
    }

    public String getPlaca() {
        return placa;
    }

    public void setPlaca(String placa) {
        this.placa = placa;
    }

    public String getTemp() {
        return temp;
    }

    public void setTemp(String temp) {
        this.temp = temp;
    }

    public String getAcid() {
        return acid;
    }

    public void setAcid(String acid) {
        this.acid = acid;
    }
}

适配器

public class MonitorAdapter extends FirestoreRecyclerAdapter<Monitor, MonitorAdapter.ViewHolder> {
    private FirebaseFirestore mFirestore = FirebaseFirestore.getInstance();
    Activity activity;
    /**
     * Create a new RecyclerView adapter that listens to a Firestore Query.  See {@link
     * FirestoreRecyclerOptions} for configuration options.
     *
     * @param options
     */
    public MonitorAdapter(@NonNull FirestoreRecyclerOptions<Monitor> options, Activity activity) {
        super(options);
        this.activity = activity;
    }

    @Override
    protected void onBindViewHolder(@NonNull ViewHolder holder, int position, @NonNull Monitor model) {
        DocumentSnapshot documentSnapshot = getSnapshots().getSnapshot(holder.getAbsoluteAdapterPosition());
        final String id = documentSnapshot.getId();
        holder.alias.setText(model.getAlias());
        holder.temp.setText(model.getTemp());
        holder.acid.setText(model.getAcid());

        holder.btn_edit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent i = new Intent(activity, VincularPlaca.class);
                i.putExtra("id_placa",id);
                activity.startActivity(i);
            }
        });

    }

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

    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView alias, temp, acid;
        Button btn_edit;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            alias = itemView.findViewById(R.id.alias);
            temp = itemView.findViewById(R.id.temp);
            acid = itemView.findViewById(R.id.acid);
            btn_edit = itemView.findViewById(R.id.btn_edit);

        }
    }

}

和我的主要活动

public class MainActivity extends AppCompatActivity {

    Button btn_add, btn_exit;
    RecyclerView mRecycler;
    MonitorAdapter mAdapter;
    FirebaseFirestore mFirestore;
    FirebaseAuth mAuth;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mFirestore = FirebaseFirestore.getInstance();
        mRecycler = findViewById(R.id.recyclerViewSingle);
        mRecycler.setLayoutManager(new LinearLayoutManager(this));
        Query query = mFirestore.collection("dispositivos");

        FirestoreRecyclerOptions<Monitor> firestoreRecyclerOptions =
                new FirestoreRecyclerOptions.Builder<Monitor>().setQuery(query,Monitor.class).build();

        mAdapter = new MonitorAdapter(firestoreRecyclerOptions, this);

        mAdapter.notifyDataSetChanged();
        mRecycler.setAdapter(mAdapter);

        btn_add = findViewById(R.id.btn_add);
        btn_exit = findViewById(R.id.btn_close);

        btn_add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(MainActivity.this,VincularPlaca.class));
            }
        });

        btn_exit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(MainActivity.this,LoginActivity.class));
                mAuth.signOut();
            }
        });

    }

    @Override
    protected void onStart() {
        super.onStart();
        mAdapter.startListening();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mAdapter.stopListening();
    }

}

【问题讨论】:

  • 没有堆栈跟踪,这意味着问题不充分。在适配器的新实例上调用 notifyDataSetChanged() 对我来说很奇怪,因为它没有任何意义。
  • 如果应用程序崩溃,则会有一个堆栈跟踪。请在 logcat 上查找,并将其添加到您的问题中。请使用@AlexMamo 回复
  • @AlexMamo 我的 Android Studio 设备管理器和模拟器无法正常工作,所以我只是构建 apk 并在物理设备上执行,所以发生此错误时我无法访问 logcat,但“崩溃”只是应用程序自行关闭当我将数据上传到 firestore 上的集合时。寻找解决方案我找到了一些方法来在另一个空隙上做文档快照,与一些“刷新按钮”或其他东西相关,再次读取数据,但我也会将 recyclerview 更改为“列表视图”。我对这些东西没有经验,我深表歉意。
  • 为什么在使用 mAdapter.startListening() 和 mAdapter.stopListening() 时编写 mAdapter.notifyDataSetChanged() ?没有意义

标签: java android firebase android-recyclerview android-adapter


【解决方案1】:
class ExampleViewModel : ViewModel() {
var mFirestore : FirebaseFirestore? = null
private val _list = MutableLiveData<FirestoreRecyclerOptions<Monitor>>()
val list: LiveData<FirestoreRecyclerOptions<Monitor>> = _list

init{
    mFirestore = FirebaseFirestore.getInstance()
    list.value= FirestoreRecyclerOptions.Builder<Monitor>().setQuery(mFirestore!!.collection("dispositivos"),Monitor::class.java).build()
}

}

【讨论】:

  • 您的答案可以通过其他支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写出好的答案的信息in the help center
【解决方案2】:

该问题已解决修复 AndroidManifest 权限和 Firebase Firestore 控制台上的代码之外,该属性应该是一个字符串但它收到一个 int。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-04
    • 2020-11-18
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    相关资源
    最近更新 更多