java - एक गतिविधि शुरू करने के लिए फायरस्टार डेटा प्राप्त होने तक प्रतीक्षा करें



android firebase (1)

मैंने POJO ऑब्जेक्ट्स की एक सूची बनाई है जो मेरे क्लाउड फायरस्टार डेटाबेस से मान प्राप्त करते हैं। यह सूची अपने आप में एक नई विशेषता बनाने वाले गुणों को पुनः प्राप्त करने के लिए एक वर्ग है। बात यह है कि सूची बनाएँ गतिविधि पर नहीं बल्कि समय के बाद भरी जाती है। मैंने लूप, कार्य, प्रतीक्षा को जोड़ने की कोशिश की है, लेकिन वांछित परिणाम नहीं मिल रहा है। यहां बताया गया है कि मैं अपने डेटा को संतोषजनक तरीके से कैसे प्राप्त करता हूं:

private void retrieveData(){
        reference = firestore.collection("attractions");
        reference.addSnapshotListener(new EventListener<QuerySnapshot>() {
            @Override
            public void onEvent(@Nullable QuerySnapshot queryDocumentSnapshots,
                                @Nullable FirebaseFirestoreException e) {
                attractionList.clear();
                for (DocumentSnapshot snapshot : queryDocumentSnapshots) {
                    Attraction attraction = snapshot.toObject(Attraction.class);
                    addAttractions(attraction);
                }
            }
        });
    }

मैं हर बार नया ऑब्जेक्ट बनाने के लिए डेटा पुनः प्राप्त करता हूं:

public AttractionList() {
        firestore.setFirestoreSettings(settings);
        reference = firestore.collection("attractions");
        attractionList = new ArrayList<>();
        retrieveData();
    }

फिर, अगर मैं बनाने पर अपनी गतिविधि पर सूची आकार की जाँच करता हूँ:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_attraction);
        Toolbar toolbar = findViewById(R.id.tb_attraction);
        setSupportActionBar(toolbar);

        //Creating POJO List and retrieving data
        attractionList = new AttractionList();
        Log.e("List Size: ", ""+attractionList.getAttractionList().size());
        //List Size: 0
    }

लेकिन अगर मैं किसी भी बटन के बाद उसी लॉग समय का उपयोग करता हूं:

@Override
    public void onBackPressed(){
        Log.e("List Size: ", ""+attractionList.getAttractionList().size());
        //List Size: 16
    }

मैं वास्तव में हर एक गतिविधि में डेटा पुनर्प्राप्त नहीं करना चाहता हूं या न ही गतिविधियों के बीच वस्तु लाने के लिए इरादा बनाना चाहता हूं। कोई तरीका है जिससे मैं इसे ठीक कर सकता हूं?

पुनश्च: यह मेरी पहली पोस्ट है। क्षमा करें, यदि मैंने इसे सही तरीके से नहीं किया है। बहुत बहुत धन्यवाद।


आप अब कुछ भी उपयोग नहीं कर सकते हैं जो अभी तक लोड नहीं किया गया है। फायरस्टार डेटा को asynchronously से लोड करता है, क्योंकि इसके लिए कुछ समय लग सकता है। आपके कनेक्शन की गति और स्थिति के आधार पर, यह डेटा उपलब्ध होने से पहले कुछ सेकंड से कुछ सेकंड तक ले सकता है। यदि आप किसी अन्य विधि के प्रकार Attraction की वस्तुओं की एक सूची को पास करना चाहते हैं, तो बस उस विधि को onSuccess() विधि से कॉल करें और उस सूची को एक तर्क के रूप में पास करें। तो एक त्वरित सुधार यह होगा:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference attractionsRef = rootRef.collection("attractions");

attractionsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<QuerySnapshot> task) {
        if (task.isSuccessful()) {
            List<Attraction> attractionsList = new ArrayList<>();
            for (QueryDocumentSnapshot document : task.getResult()) {
                Attraction attraction = document.toObject(Attraction.class);
                attractionsList.add(attraction);
            }
            methodToProcessTheList(attractionsList);
        }
    }
});

तो याद रखें, onSuccess() विधि में एक अतुल्यकालिक व्यवहार होता है, जिसका अर्थ है कि आपके डेटाबेस से डेटा प्राप्त करने से पहले भी इसे कहा जाता है। यदि आप उस विधि के बाहर के attractionsList का उपयोग करना चाहते हैं, तो आपको अपना callback बनाने की आवश्यकता है। इसे प्राप्त करने के लिए, पहले आपको एक इंटरफ़ेस बनाने की आवश्यकता है:

public interface MyCallback {
    void onCallback(List<Attraction> attractionsList);
}

फिर आपको एक विधि बनाने की आवश्यकता है जो वास्तव में डेटाबेस से डेटा प्राप्त कर रही है। यह विधि इस तरह दिखनी चाहिए:

public void readData(MyCallback myCallback) {
    attractionsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) {
            if (task.isSuccessful()) {
                List<Attraction> attractionsList = new ArrayList<>();
                for (QueryDocumentSnapshot document : task.getResult()) {
                    Attraction attraction = snapshot.toObject(Attraction.class);
                    attractionsList.add(attraction);
                }
                myCallback.onCallback(attractionsList);
            }
        }
    });
}

अंत में बस readData() विधि को कॉल करें और MyCallback इंटरफ़ेस के एक उदाहरण को एक तर्क के रूप में MyCallback करें जहाँ आपको इस तरह की आवश्यकता हो:

readData(new MyCallback() {
    @Override
    public void onCallback(List<Attraction> attractionsList) {
        //Do what you need to do with your list
    }
});

यह एकमात्र तरीका है जिसमें आप onSuccess() पद्धति से उस attractionsList वस्तु का उपयोग कर सकते हैं। अधिक जानकारी के लिए, आप इस video भी देख सकते हैं।





google-cloud-firestore