2017-05-31 32 views
8

Próbowałem kod ekstrakcji danych z wielu miejsc, ale wszędzie mogę uzyskać, jak odzyskać dane na prostej liście. Ponieważ struktura mojego JSON jest złożona i nie mogę go teraz zmienić, proszę pomóż mi w pobieraniu danych z bazy danych Firebase. Proszę o pomoc, ponieważ nie rozumiem kodu Firebase. Oto mój kod i bazy danych JSON: enter image description hereJak odzyskać dane z bazy danych Firebase, która ma strukturę zagnieżdżonych tablic i obiektów?

CategoryModel.xml

package com.example.firedb; 

import android.os.Parcel; 
import android.os.Parcelable; 

import java.util.ArrayList; 

/** 
* Created by Android on 5/31/2017. 
*/ 

public class CategoryModel { 

    private ArrayList<CategoryList> categoryList; 

    public CategoryModel() { 
    } 

    public CategoryModel(ArrayList<CategoryList> categoryList) { 
     this.categoryList = categoryList; 
    } 

    public ArrayList<CategoryList> getCategoryList() { 
     return categoryList; 
    } 

    public void setCategoryList(ArrayList<CategoryList> categoryList) { 
     this.categoryList = categoryList; 
    } 


    // CategoryList 

    public static class CategoryList { 

     public int Category_id; 
     public String Category_name; 
     public ArrayList<String>Emails; 
     public ArrayList<String>Epabx; 
     public ArrayList<String>Category_Fax; 
     public ArrayList<Persons> persons; 

     public CategoryList() { 
     } 
     //constructor of CategoryList 

     public CategoryList(int category_id, String category_name, 
          ArrayList<String> emails, ArrayList<String> epabx, ArrayList<String> category_Fax, 
          ArrayList<Persons> persons) { 
      Category_id = category_id; 
      Category_name = category_name; 
      Emails = emails; 
      Epabx = epabx; 
      Category_Fax = category_Fax; 
      this.persons = persons; 
     } 

     // getters and setters of CategoryList 

     public int getCategory_id() { 
      return Category_id; 
     } 

     public void setCategory_id(int category_id) { 
      Category_id = category_id; 
     } 

     public String getCategory_name() { 
      return Category_name; 
     } 

     public void setCategory_name(String category_name) { 
      Category_name = category_name; 
     } 

     public ArrayList<String> getEmails() { 
      return Emails; 
     } 

     public void setEmails(ArrayList<String> emails) { 
      Emails = emails; 
     } 

     public ArrayList<String> getEpabx() { 
      return Epabx; 
     } 

     public void setEpabx(ArrayList<String> epabx) { 
      Epabx = epabx; 
     } 

     public ArrayList<String> getCategory_Fax() { 
      return Category_Fax; 
     } 

     public void setCategory_Fax(ArrayList<String> category_Fax) { 
      Category_Fax = category_Fax; 
     } 

     public ArrayList<Persons> getPersons() { 
      return persons; 
     } 

     public void setPersons(ArrayList<Persons> persons) { 
      this.persons = persons; 
     } 


    } 

    //Persons 

    public static class Persons { 

     private int Person_ID; 
     private String Name; 
     private String Designation; 
     private ArrayList<String> Office_Phone; 
     private ArrayList<String> Residence_Phone; 
     private String VOIP; 
     private String Address; 
     private ArrayList<String>Fax; 
     private String Ext; 
     private ArrayList<String>Extra_info; 
     private String Category_name; 

     public Persons() { 
     } 

     // Constructor of Persons 
     public Persons(int person_ID, String name, String designation, ArrayList<String> office_Phone, 
         ArrayList<String> residence_Phone, String VOIP, String address, ArrayList<String> fax, String ext, 
         ArrayList<String>extra_info, String category_name) { 
      Person_ID = person_ID; 
      Name = name; 
      Designation = designation; 
      Office_Phone = office_Phone; 
      Residence_Phone = residence_Phone; 
      this.VOIP = VOIP; 
      Address = address; 
      Fax = fax; 
      Ext = ext; 
      Extra_info=extra_info; 
      Category_name=category_name; 
     } 

     // Getter and Setters of Persons 

     public int getPerson_ID() { 
      return Person_ID; 
     } 

     public void setPerson_ID(int person_ID) { 
      Person_ID = person_ID; 
     } 

     public String getName() { 
      return Name; 
     } 

     public void setName(String name) { 
      Name = name; 
     } 

     public String getDesignation() { 
      return Designation; 
     } 

     public void setDesignation(String designation) { 
      Designation = designation; 
     } 

     public ArrayList<String> getOffice_Phone() { 
      return Office_Phone; 
     } 

     public void setOffice_Phone(ArrayList<String> office_Phone) { 
      Office_Phone = office_Phone; 
     } 

     public ArrayList<String> getResidence_Phone() { 
      return Residence_Phone; 
     } 

     public void setResidence_Phone(ArrayList<String> residence_Phone) { 
      Residence_Phone = residence_Phone; 
     } 

     public String getVOIP() { 
      return VOIP; 
     } 

     public void setVOIP(String VOIP) { 
      this.VOIP = VOIP; 
     } 

     public String getAddress() { 
      return Address; 
     } 

     public void setAddress(String address) { 
      Address = address; 
     } 

     public ArrayList<String> getFax() { 
      return Fax; 
     } 

     public void setFax(ArrayList<String> fax) { 
      Fax = fax; 
     } 

     public String getExt() { 
      return Ext; 
     } 

     public void setExt(String ext) { 
      Ext = ext; 
     } 

     public ArrayList<String> getExtra_info() { 
      return Extra_info; 
     } 

     public void setExtra_info(ArrayList<String> extra_info) { 
      Extra_info = extra_info; 
     } 

     public String getCategory_name() { 
      return Category_name; 
     } 

     public void setCategory_name(String category_name) { 
      Category_name = category_name; 
     } 

    } 

} 

CardviewActivity:Wcześniej użyłem pliku zasobu, ale teraz chcę, aby uzyskać dane z Firebase którego kod jest niejednoznaczny online

package com.example.firedb; 

import android.content.Intent; 
import android.graphics.Color; 
import android.graphics.drawable.Drawable; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 
import android.support.v7.widget.Toolbar; 
import android.text.Editable; 
import android.text.LoginFilter; 
import android.text.TextWatcher; 
import android.util.Log; 
import android.view.Gravity; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.RelativeLayout; 
import android.widget.TextView; 

import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import java.io.IOException; 
import java.io.InputStream; 
import java.util.ArrayList; 

import static android.R.attr.button; 


public class CardViewActivity extends AppCompatActivity { 
    Toolbar mActionBarToolbar; 
    private RecyclerView mainRecyclerView; 
    private RecyclerView.Adapter mainAdapter; 
    private RecyclerView.LayoutManager mainLayoutManager; 
    private static String LOG_TAG = "CardViewActivity"; 
    EditText inputSearchMain; 
    private ArrayList<CategoryModel.CategoryList> categoryLists; 
    TextView toolbar_title_main; 
    ImageView back_cardviewActivity; 
// DatabaseHandler db; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_card_view); 

//   db = new DatabaseHandler (CardViewActivity.this); 

     mActionBarToolbar = (Toolbar) findViewById(R.id.tool_bar); 
     toolbar_title_main=(TextView)findViewById(R.id.toolbar_title); 


//  mActionBarToolbar.setTitle("Hry. Govt. Telephone Directory"); 
     // mActionBarToolbar.setLogo(R.drawable.logotoolbar); 

//  mActionBarToolbar.setTitleMargin(5,2,2,2); 
     setSupportActionBar(mActionBarToolbar); 
     getSupportActionBar().setDisplayShowTitleEnabled(false); 
     toolbar_title_main.setText("Hry. Govt. Telephone Directory"); 
     back_cardviewActivity=(ImageView)findViewById(R.id.back); 
     back_cardviewActivity.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       onBackPressed(); 
      } 
     }); 

     categoryLists=new ArrayList<CategoryModel.CategoryList>(); 
     categoryLists.addAll(getmcategoryset()); 
     mainRecyclerView=(RecyclerView)findViewById(R.id.recyclerView_Main); 
     mainRecyclerView.setHasFixedSize(true); 
     mainLayoutManager=new LinearLayoutManager(this); 
     mainRecyclerView.setLayoutManager(mainLayoutManager); 
//  Log.d("onCreate: ", "List Size: "+categoryLists.size()); 
     mainAdapter=new RecyclerViewAdapterMain(getmcategoryset()); 
     mainRecyclerView.setAdapter(mainAdapter); 
     inputSearchMain = (EditText) findViewById(R.id.inputSearchMain); 

     addTextListener(); 
    } 

    public void addTextListener(){ 

     inputSearchMain.addTextChangedListener(new TextWatcher() { 

      public void afterTextChanged(Editable s) {} 

      public void beforeTextChanged(CharSequence s, int start, int count, int after) {} 

      public void onTextChanged(CharSequence query, int start, int before, int count) { 

       query = query.toString().toLowerCase(); 

       final ArrayList<CategoryModel.CategoryList> filteredList = new ArrayList<CategoryModel.CategoryList>(); 

       for (int i = 0; i < categoryLists.size(); i++) { 

        final String text = categoryLists.get(i).getCategory_name().toLowerCase(); 
        if (text.contains(query)) { 

         filteredList.add(categoryLists.get(i)); 
        } 
       } 

       mainRecyclerView.setLayoutManager(new LinearLayoutManager(CardViewActivity.this)); 
       mainAdapter = new RecyclerViewAdapterMain(filteredList); 
       mainRecyclerView.setAdapter(mainAdapter); 
       mainAdapter.notifyDataSetChanged(); // data set changed 
      } 
     }); 
    } 

    private ArrayList<CategoryModel.CategoryList> getmcategoryset() { 
//  JSONObject obj = new JSONObject(readJSONFromAsset()); 

     try { 

      ArrayList<CategoryModel.CategoryList>categoryList = new ArrayList<CategoryModel.CategoryList>(); 
      JSONObject jsonObject = new JSONObject(readJSONFromAsset()); 

      JSONArray categoryArray = jsonObject.getJSONArray("Category"); 
      Log.d("getmcategoryset", "category count: "+categoryArray.length()); 
      for (int i = 0; i < categoryArray.length(); i++) 
      { 
       JSONObject job = categoryArray.getJSONObject(i); 

       int categoryId = job.getInt("Category_id"); 
       String categoryName = job.getString("Category_name"); 

       //this is for email array 
       ArrayList<String> emails = new ArrayList<>(); 
       JSONArray emailArray = job.getJSONArray("Emails"); 
       for (int j = 0; j< emailArray.length(); j++){ 
//     JSONObject jobE = emailArray.getString(j); 
        emails.add(emailArray.getString(j)); 
       } 

       //This i for Epabx array 
       ArrayList<String> epabx = new ArrayList<>(); 
       JSONArray epabxArray = job.getJSONArray("Epabx"); 
       for (int j = 0; j < epabxArray.length(); j++){ 
//     JSONObject jobE = epabxArray.getString(j); 
        epabx.add(epabxArray.getString(j)); 
       } 

       //This i for Category_Fax array 
       ArrayList<String> category_Fax = new ArrayList<>(); 
       JSONArray category_FaxJson = job.getJSONArray("Category_Fax"); 
       for (int j = 0; j < category_FaxJson.length(); j++){ 
//     JSONObject jobE = category_FaxJson.getString(j); 
        category_Fax.add(category_FaxJson.getString(j)); 
       } 

       //This i for Persons array 
       ArrayList<CategoryModel.Persons> personsList = new ArrayList<>(); 
       JSONArray personsArray = job.getJSONArray("Persons"); 
       for (int j = 0; j < personsArray.length(); j++){ 
        JSONObject jobIn = personsArray.getJSONObject(j); 

        int Person_ID = jobIn.getInt("Person_ID"); 
        String Name = jobIn.getString("Name"); 
        String Designation = jobIn.getString("Designation"); 

        //this is for Office_Phone array 
        ArrayList<String>Office_Phone = new ArrayList<>(); 
        JSONArray office_Phone = jobIn.getJSONArray("Office_Phone"); 
        for (int k=0; k < office_Phone.length(); k++) 
        { 
         Office_Phone.add(office_Phone.getString(k)); 
        } 

        //this is for Residence_Phone array 
        ArrayList<String>Residence_Phone = new ArrayList<>(); 
        JSONArray residence_Phone = jobIn.getJSONArray("Residence_Phone"); 
        for (int k=0; k < residence_Phone.length(); k++) 
        { 
         Residence_Phone.add(residence_Phone.getString(k)); 
        } 

        String VOIP = jobIn.getString("VOIP"); 
        String Address = jobIn.getString("Address"); 


        //this is for Fax array 
        ArrayList<String>Fax = new ArrayList<>(); 
        JSONArray fax = jobIn.getJSONArray("Fax"); 
        for (int k=0; k < fax.length(); k++) 
        { 
         Fax.add(fax.getString(k)); 
        } 

        String Ext = jobIn.getString("Ext"); 

        //this is for Extra_info array 
        ArrayList<String>Extra_info = new ArrayList<>(); 
        JSONArray extra_info = jobIn.getJSONArray("Extra_info"); 
        for (int k=0; k < extra_info.length(); k++) 
        { 
         Extra_info.add(extra_info.getString(k)); 
        } 

        personsList.add(new CategoryModel.Persons(Person_ID, Name, Designation, Office_Phone, Residence_Phone, 
          VOIP, Address, Fax, Ext,Extra_info,categoryName)); 
//     db.addPerson(new CategoryModel.Persons(Person_ID, Name, Designation, Office_Phone, Residence_Phone, 
//       VOIP, Address, Fax, Ext,Extra_info)); 
       } 

       //here your Category[] value store in categoryArrayList 
       categoryList.add(new CategoryModel.CategoryList(categoryId, categoryName, emails, epabx, category_Fax, personsList)); 

//    db.addCategory(new CategoryModel.CategoryList(categoryId, categoryName, emails, epabx, category_Fax, personsList)); 

       Log.i("categoryList size = ", ""+categoryArray.length()); 
       Log.i("cat_name=",""+categoryName); 
      } 

      if (categoryList != null) 
      { 
       Log.i("categoryList size = ", ""+categoryArray.length()); 
      } 
      return categoryList; 
     } catch (JSONException e) { 
      e.printStackTrace(); 
      return null; 
     } 

    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
//  ((RecyclerViewAdapterMain) mainAdapter).setOnItemClickListener(new RecyclerViewAdapterMain() 
//    .CategoryClickListener() { 
//   public void onItemClick(int position, View v) { 
//    Log.i(LOG_TAG, " Clicked on Item " + position); 
//   } 
//  }); 
    } 


} 

RecyclerViewAdapter:

package com.example.firedb; 

import android.content.Context; 
import android.content.Intent; 
import android.os.Bundle; 
import android.support.v7.widget.RecyclerView; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 

import java.util.ArrayList; 
import java.util.Arrays; 


public class RecyclerViewAdapterMain extends RecyclerView.Adapter<RecyclerViewAdapterMain.CategoryObjectHolder> { 
    private static String LOG_TAG = "categoryRecyclrVwAdptr"; 
    private ArrayList<CategoryModel.CategoryList> mcategoryset; 
    private static CategoryClickListener categoryClickListener; 

    public static class CategoryObjectHolder extends RecyclerView.ViewHolder { 
     TextView category_name; 
     /*TextView category_emails; 
     TextView category_epabx; 
     TextView category_fax;*/ 

     public CategoryObjectHolder(View itemView){ 
      super(itemView); 
      category_name=(TextView)itemView.findViewById(R.id.category_name); 
      /*category_emails=(TextView)itemView.findViewById(R.id.category_emails); 
      category_epabx=(TextView)itemView.findViewById(R.id.category_epabx); 
      category_fax=(TextView)itemView.findViewById(R.id.category_fax);*/ 
      Log.i(LOG_TAG, "Adding Listener"); 

     } 
//  @Override 
//  public void onClick(View v) { 
//   categoryClickListener.onItemClick(getAdapterPosition(), v); 
//  } 
    } 
// public void setOnItemClickListener(CategoryClickListener categoryClickListener) { 
//  this.categoryClickListener = categoryClickListener; 
// } 

    public RecyclerViewAdapterMain(ArrayList<CategoryModel.CategoryList> myDataset) { 
     mcategoryset = myDataset; 
    } 

    public CategoryObjectHolder onCreateViewHolder(ViewGroup parent,int viewType){ 
     View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view_row_main_activity,parent,false); 
     CategoryObjectHolder categoryObjectHolder=new CategoryObjectHolder(view); 
     return categoryObjectHolder; 
    } 

    @Override 
    public void onBindViewHolder(CategoryObjectHolder holder, final int position) { 
     /*final StringBuilder stringBuilder_emails = new StringBuilder(); 
     for (String email : mcategoryset.get(position).getEmails()) { 
      if (!stringBuilder_emails.toString().isEmpty()) { 
       stringBuilder_emails.append(", "); 
      } 
      stringBuilder_emails.append(email); 
     } 

     final StringBuilder stringBuilder_Epabx = new StringBuilder(); 
     for (String epabx : mcategoryset.get(position).getEpabx()) { 
      if (!stringBuilder_Epabx.toString().isEmpty()) { 
       stringBuilder_Epabx.append(", "); 
      } 
      stringBuilder_Epabx.append(epabx); 
     } 

     final StringBuilder stringBuilder_Category_Fax = new StringBuilder(); 
     for (String category_Fax : mcategoryset.get(position).getCategory_Fax()) { 
      if (!stringBuilder_Category_Fax.toString().isEmpty()) { 
       stringBuilder_Category_Fax.append(", "); 
      } 
      stringBuilder_Category_Fax.append(category_Fax); 
     }*/ 

     holder.category_name.setText(mcategoryset.get(position).getCategory_name()); 
     /*holder.category_emails.setText(stringBuilder_emails.toString()); 
     holder.category_epabx.setText(stringBuilder_Epabx.toString()); 
     holder.category_fax.setText(stringBuilder_Category_Fax.toString());*/ 
     holder.itemView.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       Intent i = new Intent (v.getContext(), PeopleListActivity.class); 
       i.putParcelableArrayListExtra("Persons",mcategoryset.get(position).getPersons()); 
       i.putStringArrayListExtra("emails",mcategoryset.get(position).getEmails()); 
       //i.putExtras(b); 
       v.getContext().startActivity(i); 

      } 
     }); 
    } 
    public void addItem(CategoryModel.CategoryList dataObj, int index) { 
     mcategoryset.add(index, dataObj); 
     notifyItemInserted(index); 
    } 

    public void deleteItem(int index) { 
     mcategoryset.remove(index); 
     notifyItemRemoved(index); 
    } 

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

    public interface CategoryClickListener { 
     public void onItemClick(int position, View v); 
    } 
} 

Odpowiedz

5

Jedynym sposobem, aby uzyskać dane z Firebase Database to używając ValueEventListener. Firebase działa z asynchronicznymi połączeniami, więc nie można wywoływać funkcji, pobierać danych i używać ich. Musisz ustawić wartość ValueEventListener w określonym odwołaniu do bazy danych.

Dla rzeczywistego problemu, musisz utworzyć tablicę, ustawić Firebase Reference, dodać ValueEventListener i wewnątrz dodać każde wystąpienie CategoryList w tablicy. Wreszcie, jeszcze wewnątrz ValueEventListener, można stworzyć swój CategoryModel z Array categorylist jako parametr, i zaktualizować UI, aby zobaczyć dane w CategoryModel:

CategoryModel categoryModel; 
ArrayList<CategoryList> array = new ArrayList<>(); 
FirebaseDatabase database = FirebaseDatabase.getInstance(); 
DatabaseReference categoryRef = database.getReference("Category"); 
categoryRef.addValueEventListener(new ValueEventListener() { 
    @Override 
    public void onDataChange(DataSnapshot dataSnapshot) { 
     // This method is called once with the initial value and again 
     // whenever data at this location is updated. 
     for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) { 
      CategoryList categoryList = childSnapshot.getValue(CategoryList.class); 
      array.add(categoryList); 
     } 
     categoryModel = new CategoryModel(array); 
     // Method to show the data in category model, 
     // usually populating an ListView or something 
     updateUI() 
    } 

    @Override 
    public void onCancelled(DatabaseError error) { 
     // Failed to read value 
     Log.w(TAG, "Failed to read value.", error.toException()); 
    } 
}); 

Aby mieć tej pracy, klasa categorylist musi implementuj wszystkie ustawiające jego członków, więc działa "datasnapshot.getValue()". Innym rozwiązaniem może być utworzenie konstruktora w categorylist że recibe się DataSnapshot w ten sposób:

public CategoryList(DataSnapshot snapshot){ 
    Category_id = snapshot.child("Category_id").getValue(int.class); 
    Category_name = snapshot.child("Category_name").getValue(String.class); 
    GenericTypeIndicator<List<String>> stringList = new GenericTypeIndicator<List<String>>() {}; 
    Emails = snapshot.child("Emails").getValue(stringList); 
    Epabx= snapshot.child("Epabx").getValue(stringList); 
    Category_Fax= snapshot.child("Category_Fax").getValue(stringList); 
    GenericTypeIndicator<List<Persons>> personsList = new GenericTypeIndicator<List<Persons>>() {}; 
    persons = snapshot.child("Persons").getValue(personsList); 
} 

Jeśli tworzysz konstruktora, trzeba zastąpić ten wiersz:

CategoryList categoryList = childSnapshot.getValue(CategoryList.class); 

z tym:

CategoryList categoryList = new CategoryList(childSnapshot); 

Widać, że używam GenericTypeIndicator do pracy ze zbiorami danych, jest to klasa pomocnika przewidywać Firebase do pracy z listami, mapy, Zestawy lub inna kolekcja.

+1

mieć na uwadze, że pierwsza litera zmiennych klasy za to nie jest dobra praktyka . Pisałem tylko w ten sposób, aby szanować twój kod. Możesz spróbować rozwiązać ten problem, aby lepiej odczytać kod, gdy korzystasz z IDE, który zapewnia kolory podświetlania składni. –

1

Tylko zalecenie! Nie jest to dobra struktura danych, należy wyekstrahować dane. Następnie można obserwować dane przez ChildEventListener lub ValueEventListener.

Na przykład:

-Category 
--CategoryId 
---CategoryList 
---Persons 
----user1: true 
----user2: true, etc. 

-Users 
--user1Id 
---user1details 
--user2Id 
---user2details, etc. 

Oto kilka przydatnych linków o denormalizing danych

Link1, Link2

+0

Polecam faktycznie alternatywne rozwiązanie problemu. Po prostu nie podaję kodu, bo nie muszę. Ponieważ nie była to wielka sprawa z właściwą strukturą bazy danych. Przed przejrzeniem postu należy poświęcić wystarczającą uwagę. – uguboz

+0

Pytanie jednoznacznie: "Ponieważ struktura mojego JSON jest złożona i nie mogę go teraz zmienić, proszę pomóżcie mi w pobieraniu danych z bazy danych Firebase". Więc polecasz, to nie jest odpowiedź, a zamiast tego może być komentarzem w pytaniu. –