2017-08-28 109 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