2017-05-31 15 views
8

Tôi đã thử mã trích xuất dữ liệu từ nhiều nơi nhưng ở khắp mọi nơi tôi có được cách lấy dữ liệu trong một danh sách đơn giản. Vì cấu trúc của JSON của tôi phức tạp và tôi không thể thay đổi nó ngay bây giờ, vì vậy hãy giúp tôi lấy dữ liệu từ cơ sở dữ liệu firebase. Vui lòng trợ giúp vì tôi không thể hiểu mã Firebase. Sau đây là mã của tôi và cơ sở dữ liệu JSON: enter image description hereLàm cách nào để truy xuất dữ liệu từ cơ sở dữ liệu firebase có cấu trúc mảng và đối tượng lồng nhau?

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:Đầu tôi đã sử dụng một tập tin tài sản nhưng bây giờ tôi muốn lấy dữ liệu từ căn cứ hỏa lực mà đang mơ hồ trực tuyến

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

Trả lời

5

Cách duy nhất để lấy dữ liệu từ cơ sở dữ liệu căn cứ hỏa lực nó sử dụng một ValueEventListener. Firebase hoạt động với các cuộc gọi không đồng bộ, do đó bạn không thể gọi hàm, lấy dữ liệu và sử dụng nó. Bạn phải thiết lập một ValueEventListener trong một tham chiếu cơ sở dữ liệu cụ thể.

Đối với vấn đề thực tế của bạn, bạn phải tạo một mảng, đặt Tham chiếu Firebase, thêm ValueEventListener và bên trong thêm mỗi lần xuất hiện của CategoryList trong mảng. Cuối cùng, vẫn bên trong ValueEventListener, bạn có thể tạo CategoryModel của bạn, với mảng của CategoryList như tham số, và cập nhật giao diện người dùng của bạn, để xem các dữ liệu trong 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()); 
    } 
}); 

Đối đã làm việc này, lớp CategoryList của bạn phải thực hiện tất cả các setters của các thành viên của mình để "datasnapshot.getValue()" hoạt động. cách tiếp cận khác có thể, tạo ra một Constructor trong CategoryList rằng recibe một DataSnapshot theo cách này:

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

Nếu bạn tạo các nhà xây dựng, bạn phải thay thế dòng này:

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

với điều này:

CategoryList categoryList = new CategoryList(childSnapshot); 

Bạn có thể thấy rằng tôi sử dụng GenericTypeIndicator để làm việc với bộ sưu tập dữ liệu, đây là lớp trợ giúp cung cấp cho Firebase hoạt động với Danh sách, Maps, Bộ hoặc một Bộ sưu tập khác.

+1

Có nhớ rằng hoa chữ cái đầu tiên của các biến của lớp nó không phải là thực hành tốt . Tôi chỉ viết theo cách đó để tôn trọng mã của bạn. Bạn có thể cố gắng khắc phục điều đó để hiểu rõ hơn về mã của bạn khi sử dụng một IDE cung cấp các màu tô sáng cú pháp. –

1

Chỉ là đề xuất! Đây không phải là cấu trúc dữ liệu tốt, bạn nên chuẩn hóa dữ liệu của mình. Sau đó, bạn có thể quan sát dữ liệu của mình theo ChildEventListener hoặc ValueEventListener.

Ví dụ:

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

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

Dưới đây là một số liên kết hữu ích về denormalizing dữ liệu của bạn

Link1, Link2

+0

Tôi đề nghị một giải pháp thay thế cho vấn đề thực sự. Tôi chỉ không cung cấp cho mã như tôi không phải. Bởi vì nó không phải là một vấn đề lớn với cấu trúc cơ sở dữ liệu thích hợp. Bạn nên chú ý đủ trước khi xem lại bài đăng. – uguboz

+0

Câu hỏi rõ ràng: "Vì cấu trúc của JSON của tôi phức tạp và tôi không thể thay đổi nó ngay bây giờ, vì vậy hãy giúp tôi lấy dữ liệu từ cơ sở dữ liệu firebase". Vì vậy, bạn đề nghị, nó không phải là một câu trả lời và thay vào đó có thể là một bình luận trong câu hỏi. –

Các vấn đề liên quan