2017-08-28 111 views
1

我是通用的firebase数据库和firebase的新手,在尝试使用它时遇到了一些小问题。DataSnapshot.getValue()不能正确检索对象

我使用下面的JSON代码我从火力控制台进口的,原来我刚刚创建的火力控制台数据库结构,那么下载的JSON代码,并如下:

{ 
    "rides" : { 
    "arrive" : "kech", 
    "depart" : "agadir", 
    "detail" : "0,1", 
    "msg" : false, 
    "phone" : true, 
    "price" : 15, 
    "profile_id" : 0, 
    "spots" : 3, 
    "timedate" : "11/12/2017 11:15", 
    "vocal_id" : 0 
    } 
} 

对象我想取回被命名为Ride.java

public class Ride { 
    private String arrive; 
    private String depart; 
    private String detail; 
    private boolean msg; 
    private boolean phone; 
    private int price; 
    private int profile_id; 
    private int spots; 
    private String timedate; 
    private int vocal_id; 

    public Ride() {} 

    // public getters (I created them I just didn't post it all to make the post shorter) 
} 

听我的数据库引用我使用下面的代码:

FirebaseDatabase database = FirebaseDatabase.getInstance(); 
     DatabaseReference ref = database.getReference("rides").child("0"); // 0 is the ride id 

     ref.addListenerForSingleValueEvent(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
       for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){ 
        Ride ride = singleSnapshot.getValue(Ride.class); 
        rides.add(ride); // list of rides used later in a listadapter 
       } 
      } 
      @Override 
      public void onCancelled(DatabaseError databaseError) { 
       Log.e(TAG, "onCancelled", databaseError.toException()); 
      } 
     }); 

我试图从firebase数据库获取一个单骑,并在我的应用程序中显示它。在firebase控制台它有网址:https://myapp.firebaseio.com/rides/0(第二骑有ID 1等)。抓住所有游乐设施的最佳做法是什么?从每个游乐设施获取其属性是什么?

编辑:当我删除.child("0")我没有得到任何错误,但没有出现在我的ListView 。显然rides.add(ride)不会出于某种原因。

我加入的一个简单的实例骑addListenerForSingleValueEvent()方法外测试它,它工作正常。

我也试过改变听者addValueEventListener(),相同的结果..

EDIT2:我得到一个错误信息,当我尝试从我的数据库中检索的整数。

我在我的数据库监听尝试这样做:

public void onDataChange(DataSnapshot dataSnapshot) { 
       for (DataSnapshot singleSnapshot: dataSnapshot.getChildren()) { 
        int price = (int) singleSnapshot.child("price").getValue(); // error takes place here 
        Log.d("FirebaseDb", String.valueOf(price)); 
       } 
      } 

结果是这样的错误:(所有整数)

java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer 
    at com.ride.ive.anas.iveride.Fragments.RidesFragment$1.onDataChange(RidesFragment.java:96) 

但是,当我取回一个字符串或布尔它工作正常,如:

String arrive = (String) singleSnapshot.child("arrive").getValue();

或者Boolean usePhone = (Boolean) singleSnapshot.child("phone").getValue();

EDIT3:这里是经@Prodigy请求RidesFragment.java文件。 其中我有一个ListView,我尝试显示存储在我的firebase数据库中的所有乘车实例。

public class RidesFragment extends Fragment { 

    ListView list; 
    RidesAdapter2 ridesAdapter; 
    List<Ride> rides; 
    Ride ride; 

    List<RidePojo> filteredRides; 
    LinearLayout layoutFilter; 
    boolean filtersVisible = false; 
    boolean searchDone = false; 

    String userNumber; 

    public RidesFragment() { 
     // Required empty public constructor 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.fragment_rides, container, false); 
     getActivity().setTitle("Search for a ride:"); 

     // filter action button stuff 
     setHasOptionsMenu(true); 
     layoutFilter = rootView.findViewById(R.id.ll_filter_screen); 

     /*FragmentManager fm = getActivity().getSupportFragmentManager(); 
     fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);*/ 

     ridesAdapter = new RidesAdapter2(getContext(), rides); 


     Bundle arguments = getArguments(); 
     list = rootView.findViewById(R.id.rides_list); 
     rides = new ArrayList<>(); 

     FirebaseDatabase database = FirebaseDatabase.getInstance(); 
     DatabaseReference ref = database.getReference("rides"); 

     ref.addListenerForSingleValueEvent(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
       for (DataSnapshot singleSnapshot: dataSnapshot.getChildren()) { 
        Ride ride = singleSnapshot.getValue(Ride.class); 
        rides.add(ride); 
        ridesAdapter.notifyDataSetChanged(); 
        Log.d("FbDatabase", singleSnapshot.toString()); 
       } 

      } 
      @Override 
      public void onCancelled(DatabaseError databaseError) { 
       Log.e(TAG, "onCancelled", databaseError.toException()); 
      } 
     }); 

     rides.add(ride); 

     // In case the rides ArrayList is not empty another fragment appears for no rides criteria 
     if(rides.isEmpty()) { 
      rootView = inflater.inflate(R.layout.fragment_empty, container, false); 
      Button rideButton = rootView.findViewById(R.id.btn_post_ride); 
      Button requestButton = rootView.findViewById(R.id.btn_post_request); 

      rideButton.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        launchFragment(new OfferRideFragment(), getActivity()); 
       } 
      }); 

      requestButton.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        launchFragment(new RequestFragment(), getActivity()); 
       } 
      }); 

     } 
     else { 
      list.setAdapter(ridesAdapter); 

     } 
     return rootView; 
    } 

    protected void launchFragment(Fragment f, FragmentActivity a) { 
     android.support.v4.app.FragmentTransaction fragmentTransaction = 
       a.getSupportFragmentManager().beginTransaction(); 
     fragmentTransaction.replace(R.id.fragment_container, f); 
     fragmentTransaction.commit(); 
    } 
// .... 
} 
+0

创建getter和为你的旅程类的东西其余制定者编辑的代码可以从这个stackoverflower答案[这里](https://stackoverflow.com/questions/30933328/how遵循-to-convert-firebase-data-to-java-object) –

+0

我创建了它们,我只是不想将它们写在这里以使文章更短 – Anas

+2

将代码添加到数据库引用的监听器的代码 –

回答

1

火力地堡数据库命名约定更像命名文件的路径,例如访问您使用.child游乐设施(“骑”),而到达将.child(“骑”)。孩子(“到达”)或(乘坐/到达)

从你发布的firebase链接,我可以看到你有一个节点骑着一个孩子节点0等.... 但从你张贴不能看节点“0”,这肯定会引发错误。

The correct Json should be 
{ 
    "rides" : { 
    "0": { 
    "arrive" : "kech", 
    "depart" : "agadir", 
    "detail" : "0,1", 
    "msg" : false, 
    "phone" : true, 
    "price" : 15, 
    "profile_id" : 0, 
    "spots" : 3, 
    "timedate" : "11/12/2017 11:15", 
    "vocal_id" : 0 
} 
    } 
} 

这将拔出你需要的数据,不要忘记在游览列表添加适配器notifydata变化侦听器添加数据时。

见下

public class RidesFragment extends Fragment { 

    ListView list; 
    RidesAdapter2 ridesAdapter; 
    List<Ride> rides; 
    Ride ride; 

    List<RidePojo> filteredRides; 
    LinearLayout layoutFilter; 
    boolean filtersVisible = false; 
    boolean searchDone = false; 

    String userNumber; 

    public RidesFragment() { 
     // Required empty public constructor 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.fragment_rides, container, false); 
     getActivity().setTitle("Search for a ride:"); 

     // filter action button stuff 
     setHasOptionsMenu(true); 
     layoutFilter = rootView.findViewById(R.id.ll_filter_screen); 

     /*FragmentManager fm = getActivity().getSupportFragmentManager(); 
     fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);*/ 




     Bundle arguments = getArguments(); 
     list = rootView.findViewById(R.id.rides_list); 
     rides = new ArrayList<>(); 
     ridesAdapter = new RidesAdapter2(getContext(), rides); 
     list.setAdapter(ridesAdapter); 

     FirebaseDatabase database = FirebaseDatabase.getInstance(); 
     DatabaseReference ref = database.getReference("rides"); 

     ref.addListenerForSingleValueEvent(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
       for (DataSnapshot singleSnapshot: dataSnapshot.getChildren()) { 
        Ride ride = singleSnapshot.getValue(Ride.class); 
        rides.add(ride); 
        ridesAdapter.notifyDataSetChanged(); 
        Log.d("FbDatabase", singleSnapshot.toString()); 
       } 

      } 
      @Override 
      public void onCancelled(DatabaseError databaseError) { 
       Log.e(TAG, "onCancelled", databaseError.toException()); 
      } 
     }); 

     //rides.add(ride); 

     // In case the rides ArrayList is not empty another fragment appears for no rides criteria 
     if(rides.isEmpty()) { 
      rootView = inflater.inflate(R.layout.fragment_empty, container, false); 
      Button rideButton = rootView.findViewById(R.id.btn_post_ride); 
      Button requestButton = rootView.findViewById(R.id.btn_post_request); 

      rideButton.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        launchFragment(new OfferRideFragment(), getActivity()); 
       } 
      }); 

      requestButton.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        launchFragment(new RequestFragment(), getActivity()); 
       } 
      }); 

     } 

     //else { 
      //list.setAdapter(ridesAdapter); 

     //} 
     return rootView; 
    } 

    protected void launchFragment(Fragment f, FragmentActivity a) { 
     android.support.v4.app.FragmentTransaction fragmentTransaction = 
       a.getSupportFragmentManager().beginTransaction(); 
     fragmentTransaction.replace(R.id.fragment_container, f); 
     fragmentTransaction.commit(); 
    } 
// .... 
} 
+0

工作正常,但没有错误,但'rides.add(骑)'仍然无法正常工作... – Anas

+0

在rides.add后添加adapter.notifyDataSetChanged()骑在里面valuechangelistener for循环。让我知道它是否有效 – Prodigy

+0

实际上,我稍后在代码中创建适配器,但我在开始时初始化它,并尝试了您所说的内容,但没有任何更改。同样的结果。 – Anas