Android Studio中Firebase getKey与getValue返回Null问题求助
问题描述
已放弃调试该问题,查阅大量相关帖子后,发现我的代码与示例代码相似,但getKey和getValue始终返回Null。我需要获取购物车中所有商品的price值来计算总价,以下是我的代码、Firebase实时数据库截图及调试器截图:
代码片段
package com.example.dejabrew; import static java.lang.Integer.parseInt; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.ImageView; import android.widget.TextView; import com.google.firebase.database.DataSnapshot; import com.google.firebase.database.DatabaseError; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; import com.google.firebase.database.ValueEventListener; import java.util.ArrayList; public class CartList extends AppCompatActivity implements RecyclerViewInterface { TextView finalprice; Integer getprice; Integer Finalprice = 0; ImageView home, favourite; RecyclerView cartrecyclerview; RecyclerViewAdapter2 recyclerViewAdapter2; ArrayList<Cartmodel> list; ArrayList<Integer> pricelist = new ArrayList<>(); DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReferenceFromUrl("https://dejabrew-2bcc8-default-rtdb.asia-southeast1.firebasedatabase.app/"); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.cartlist); finalprice = (TextView) findViewById(R.id.finalprice); cartrecyclerview = (RecyclerView)findViewById(R.id.cartrecyclerview); cartrecyclerview.setHasFixedSize(true); home = (ImageView) findViewById(R.id.home2); favourite = (ImageView) findViewById(R.id.heart2); RecyclerView.LayoutManager layoutManager = (new LinearLayoutManager(this)); cartrecyclerview.setLayoutManager(layoutManager); list = new ArrayList<>(); recyclerViewAdapter2 = new RecyclerViewAdapter2(this, this, list); cartrecyclerview.setAdapter(recyclerViewAdapter2); databaseReference.child("AddtoCart").child("Orders").addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { list.clear(); for (DataSnapshot dataSnapshot : snapshot.getChildren()){ Cartmodel cartmodel = dataSnapshot.getValue(Cartmodel.class); list.add(cartmodel); } recyclerViewAdapter2.notifyDataSetChanged(); } @Override public void onCancelled(@NonNull DatabaseError error) { } }); databaseReference.child("AddtoCart").child("Orders").addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot1) {; for (DataSnapshot dataSnapshot1: snapshot1.getChildren()){ String getkey = dataSnapshot1.getKey(); getprice = snapshot1.child(getkey).child("price").getValue(Integer.class); } } @Override public void onCancelled(@NonNull DatabaseError error) { } }); home.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(CartList.this, HomePage.class); startActivity(intent); } }); } @Override public void onitemclick(int position) { Cartmodel cartmodel = list.get(position); String id = cartmodel.getItemid(); databaseReference.child("AddtoCart").child("Orders").child(id).removeValue(); recyclerViewAdapter2.notifyItemRemoved(position); } }
截图说明
- 数据库截图:展示
AddtoCart/Orders节点下的结构,每个子节点包含price等字段 - 调试器截图:显示
getkey和getprice变量为Null
问题原因及解决方案
核心问题
第二个ValueEventListener中的取值逻辑错误:
getprice = snapshot1.child(getkey).child("price").getValue(Integer.class);
snapshot1是Orders节点的快照,dataSnapshot1已经是它的子节点(单个订单),直接通过dataSnapshot1.child("price")即可获取对应值,无需通过snapshot1.child(getkey)重复定位路径,这会导致路径错误返回Null。
修复后的总价计算逻辑
替换第二个ValueEventListener为以下代码,同时完成总价累加与UI更新:
databaseReference.child("AddtoCart").child("Orders").addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot1) { Finalprice = 0; // 每次数据更新时重置总价 for (DataSnapshot dataSnapshot1: snapshot1.getChildren()){ Integer price = dataSnapshot1.child("price").getValue(Integer.class); if (price != null) { // 空值校验,避免崩溃 Finalprice += price; } } finalprice.setText(String.valueOf(Finalprice)); // 更新总价显示 } @Override public void onCancelled(@NonNull DatabaseError error) { // 可添加错误提示逻辑 } });
额外优化建议
- 合并监听事件:无需两个独立的
ValueEventListener,可在第一个监听中同时完成列表更新和总价计算,减少数据库请求:
databaseReference.child("AddtoCart").child("Orders").addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { list.clear(); Finalprice = 0; for (DataSnapshot dataSnapshot : snapshot.getChildren()){ Cartmodel cartmodel = dataSnapshot.getValue(Cartmodel.class); list.add(cartmodel); // 直接从解析后的模型取price,更简洁 if (cartmodel != null && cartmodel.getPrice() != null) { Finalprice += cartmodel.getPrice(); } } recyclerViewAdapter2.notifyDataSetChanged(); finalprice.setText(String.valueOf(Finalprice)); } @Override public void onCancelled(@NonNull DatabaseError error) { } });
- 检查CartModel类:确保类的字段名与数据库键完全一致(含大小写),且提供
getPrice()等getter方法,否则dataSnapshot.getValue(Cartmodel.class)无法正确解析数据。 - 空值安全处理:所有数据库取值操作都需做空值判断,避免空指针异常。
内容的提问来源于stack exchange,提问作者killersea
相关产品推荐
相关产品推荐

