【问题标题】:How to retrieve data from firebase database which is having nested array and objects structure?如何从具有嵌套数组和对象结构的 Firebase 数据库中检索数据?
【发布时间】:2017-11-01 07:16:05
【问题描述】:

我尝试了很多地方的数据提取代码,但我到处都知道如何在一个简单的列表中检索数据。由于我的 JSON 结构很复杂,我现在无法更改它,所以请帮助我从 firebase 数据库中检索数据。 请帮忙,因为我无法理解 Firebase 代码。以下是我的代码和 JSON 数据库:

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: 之前我使用的是资产文件,但现在我想从代码在网上不明确的 firebase 获取数据

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);
    }
}

【问题讨论】:

    标签: android json firebase firebase-realtime-database


    【解决方案1】:

    从 Firebase 数据库获取数据的唯一方法是使用 ValueEventListener。 Firebase 使用异步调用,因此您无法调用该函数、获取数据并使用它。您必须在特定的数据库引用中设置一个 ValueEventListener。

    对于您的实际问题,您必须创建一个数组,设置 Firebase 引用,添加 ValueEventListener 并在数组中添加每个出现的 CategoryList。最后,仍然在 ValueEventListener 内部,您可以创建 CategoryModel,使用 CategoryList 的数组作为参数,并更新您的 UI,以查看 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());
        }
    });
    

    为了让这个工作正常,您的 CategoryList 类必须实现其成员的所有设置器,以便“datasnapshot.getValue()”工作。 另一种方法是,在 CategoryList 中创建一个构造函数,以这种方式接收 DataSnapshot:

    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);
    }
    

    如果创建构造函数,则必须替换此行:

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

    用这个:

    CategoryList categoryList = new CategoryList(childSnapshot);
    

    您可以看到我使用GenericTypeIndicator 来处理数据集合,这是为 Firebase 提供的帮助器类,用于处理列表、地图、集合或其他集合。

    【讨论】:

    • 请记住,将类变量的第一个字母大写是不好的做法。我写这种方式只是为了尊重你的代码。当使用提供语法高亮颜色的 IDE 时,您可以尝试修复该问题以便更好地阅读您的代码。
    【解决方案2】:

    只是一个建议!这不是一个好的数据结构,你应该对你的数据进行反规范化。然后你可以通过ChildEventListenerValueEventListener观察你的数据。

    例如:

    -Category
    --CategoryId
    ---CategoryList
    ---Persons
    ----user1: true
    ----user2: true, etc.
    
    -Users
    --user1Id
    ---user1details
    --user2Id
    ---user2details, etc.
    

    这里有一些关于非规范化数据的有用链接

    Link1, Link2

    【讨论】:

    • 我实际上推荐了一个替代解决方案。我只是不提供代码,因为我不需要。因为正确的数据库结构并不是什么大问题。在查看帖子之前,您应该给予足够的关注。
    • 问题明确:“由于我的 JSON 结构很复杂,我现在无法更改它,所以请帮助我从 firebase 数据库中检索数据”。因此,您的建议不是答案,而是可以作为问题中的评论。
    猜你喜欢
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 1970-01-01
    • 2017-07-09
    • 1970-01-01
    • 2017-02-12
    相关资源
    最近更新 更多