इस पेज का अनुवाद Cloud Translation API से किया गया है.
Switch to English

Android पर डेटा पढ़ें और लिखें

इस दस्तावेज़ में फायरबेस डेटा पढ़ने और लिखने की मूल बातें शामिल हैं।

Firebase डेटा को FirebaseDatabase संदर्भ में लिखा जाता है और संदर्भ में एक अतुल्यकालिक श्रोता को संलग्न करके पुनर्प्राप्त किया जाता है। श्रोता को डेटा की प्रारंभिक स्थिति के लिए एक बार ट्रिगर किया जाता है और फिर कभी भी डेटा बदल जाता है।

एक DatabaseReference प्राप्त करें

पढ़ने के लिए या लिखने डेटा डेटाबेस से, आप का एक उदाहरण की जरूरत DatabaseReference :

जावा

private DatabaseReference mDatabase;
// ...
mDatabase = FirebaseDatabase.getInstance().getReference();

Kotlin + KTX

private lateinit var database: DatabaseReference
// ...
database = Firebase.database.reference

डेटा पढ़ें और लिखें

मूल लेखन कार्य

मूल लिखने के संचालन के लिए, आप setValue() को निर्दिष्ट संदर्भ में डेटा को बचाने के लिए उपयोग कर सकते हैं, उस रास्ते पर किसी भी मौजूदा डेटा को बदल सकते हैं। आप इस विधि का उपयोग कर सकते हैं:

  • पास प्रकार जो उपलब्ध JSON प्रकार के अनुरूप हैं:
    • String
    • Long
    • Double
    • Boolean
    • Map<String, Object>
    • List<Object>
  • एक कस्टम जावा ऑब्जेक्ट पास करें, यदि यह परिभाषित करने वाला वर्ग एक डिफ़ॉल्ट कंस्ट्रक्टर है जो कोई तर्क नहीं लेता है और जिसके पास गुणों को असाइन करने के लिए सार्वजनिक गेटर्स हैं।

यदि आप एक जावा ऑब्जेक्ट का उपयोग करते हैं, तो आपके ऑब्जेक्ट की सामग्री स्वचालित रूप से एक नेस्टेड फैशन में बाल स्थानों पर मैप की जाती है। जावा ऑब्जेक्ट का उपयोग करना भी आमतौर पर आपके कोड को अधिक पठनीय और बनाए रखने में आसान बनाता है। उदाहरण के लिए, यदि आपके पास मूल उपयोगकर्ता प्रोफ़ाइल वाला कोई ऐप है, तो आपकी User ऑब्जेक्ट निम्नानुसार दिख सकती है:

जावा

@IgnoreExtraProperties
public class User {

    public String username;
    public String email;

    public User() {
        // Default constructor required for calls to DataSnapshot.getValue(User.class)
    }

    public User(String username, String email) {
        this.username = username;
        this.email = email;
    }

}

Kotlin + KTX

@IgnoreExtraProperties
data class User(
    var username: String? = "",
    var email: String? = ""
)

आप एक उपयोगकर्ता को setValue() में निम्नानुसार जोड़ सकते हैं:

जावा

private void writeNewUser(String userId, String name, String email) {
    User user = new User(name, email);

    mDatabase.child("users").child(userId).setValue(user);
}

Kotlin + KTX

private fun writeNewUser(userId: String, name: String, email: String?) {
    val user = User(name, email)
    database.child("users").child(userId).setValue(user)
}

इस तरह setValue() का उपयोग करने से किसी भी बच्चे के नोड्स सहित निर्दिष्ट स्थान पर डेटा ओवरराइट हो जाता है। हालाँकि, आप अभी भी पूरे ऑब्जेक्ट को दोबारा लिखे बिना एक बच्चे को अपडेट कर सकते हैं। यदि आप उपयोगकर्ताओं को अपनी प्रोफ़ाइल अपडेट करने की अनुमति देना चाहते हैं, तो आप इस प्रकार उपयोगकर्ता नाम को अपडेट कर सकते हैं:

जावा

mDatabase.child("users").child(userId).child("username").setValue(name);

Kotlin + KTX

database.child("users").child(userId).child("username").setValue(name)

मूल्य घटनाओं के लिए सुनो

एक पथ पर डेटा पढ़ सकते हैं और बदलावों को सुनने के लिए, का उपयोग addValueEventListener() या addListenerForSingleValueEvent() एक जोड़ने के लिए विधि ValueEventListener एक को DatabaseReference

श्रोता इवेंट कॉलबैक विशिष्ट उपयोग
ValueEventListener onDataChange() किसी पथ की संपूर्ण सामग्री में परिवर्तन के लिए पढ़ें और सुनें।

आप दिए गए पथ पर सामग्री के एक स्थिर स्नैपशॉट को पढ़ने के लिए onDataChange() विधि का उपयोग कर सकते हैं, क्योंकि वे घटना के समय मौजूद थे। यह विधि एक बार तब शुरू हो जाती है जब श्रोता संलग्न होता है और फिर से हर बार डेटा, जिसमें बच्चे भी शामिल हैं, बदलता है। ईवेंट कॉलबैक एक स्नैपशॉट है जिसमें उस स्थान पर सभी डेटा होते हैं, जिसमें चाइल्ड डेटा भी शामिल है। यदि कोई डेटा नहीं है, तो जब आप exists() होते हैं, तब स्नैपशॉट false वापस आ जाएगा exists() और जब आप उस पर getValue() कॉल करते हैं, तो null हो जाता है।

निम्नलिखित उदाहरण डेटाबेस से एक पोस्ट के विवरण को पुनः प्राप्त करने वाले एक सामाजिक ब्लॉगिंग एप्लिकेशन को प्रदर्शित करता है:

जावा

ValueEventListener postListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        // Get Post object and use the values to update the UI
        Post post = dataSnapshot.getValue(Post.class);
        // ...
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        // Getting Post failed, log a message
        Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
        // ...
    }
};
mPostReference.addValueEventListener(postListener);

Kotlin + KTX

val postListener = object : ValueEventListener {
    override fun onDataChange(dataSnapshot: DataSnapshot) {
        // Get Post object and use the values to update the UI
        val post = dataSnapshot.getValue<Post>()
        // ...
    }

    override fun onCancelled(databaseError: DatabaseError) {
        // Getting Post failed, log a message
        Log.w(TAG, "loadPost:onCancelled", databaseError.toException())
        // ...
    }
}
postReference.addValueEventListener(postListener)

श्रोता को एक DataSnapshot प्राप्त होता है, जिसमें घटना के समय डेटाबेस में निर्दिष्ट स्थान पर डेटा होता है। एक स्नैपशॉट पर getValue() को कॉल करना डेटा के जावा ऑब्जेक्ट प्रतिनिधित्व को लौटाता है। यदि स्थान पर कोई डेटा मौजूद नहीं है, तो getValue() रिटर्न null getValue()

इस उदाहरण में, ValueEventListener भी onCancelled() विधि को परिभाषित करता है जिसे रीड रद्द कर दिया जाता है। उदाहरण के लिए, यदि क्लाइंट को फायरबेस डेटाबेस स्थान से पढ़ने की अनुमति नहीं है, तो एक रीड को रद्द किया जा सकता है। यह विधि एक DatabaseError ऑब्जेक्ट पारित करती है जो DatabaseError बताती है कि विफलता क्यों हुई।

एक बार डेटा पढ़ें

कुछ मामलों में आप चाहते हैं कि कॉलबैक को एक बार कॉल किया जाए और फिर तुरंत हटा दिया जाए, जैसे कि यूआई तत्व को इनिशियलाइज़ करते समय जिसे आप बदलने की उम्मीद नहीं करते हैं। आप इस परिदृश्य को सरल बनाने के लिए addListenerForSingleValueEvent() विधि का उपयोग कर सकते हैं: यह एक बार ट्रिगर होता है और फिर दोबारा ट्रिगर नहीं होता है।

यह उन डेटा के लिए उपयोगी है जिन्हें केवल एक बार लोड करने की आवश्यकता होती है और अक्सर बदलने या सक्रिय सुनने की आवश्यकता नहीं होती है। उदाहरण के लिए, पिछले उदाहरणों में ब्लॉगिंग ऐप इस पद्धति का उपयोग उपयोगकर्ता की प्रोफ़ाइल को लोड करने के लिए करता है जब वे एक नई पोस्ट लिखना शुरू करते हैं:

डेटा को अपडेट करना या हटाना

विशिष्ट फ़ील्ड अपडेट करें

एक साथ नोड के विशिष्ट बच्चों को अन्य बच्चे के नोड्स को अधिलेखित करने के लिए लिखने के लिए, updateChildren() विधि का उपयोग करें।

updateChildren() कॉल करते updateChildren() , आप कुंजी के लिए एक पथ निर्दिष्ट करके निचले स्तर के बाल मूल्यों को अपडेट कर सकते हैं। यदि डेटा को बेहतर बनाने के लिए कई स्थानों पर संग्रहीत किया जाता है, तो आप डेटा फ़ैन-आउट का उपयोग करके उस डेटा के सभी उदाहरणों को अपडेट कर सकते हैं । उदाहरण के लिए, एक सामाजिक ब्लॉगिंग ऐप में Post क्लास इस तरह हो सकती है:

जावा

@IgnoreExtraProperties
public class Post {

    public String uid;
    public String author;
    public String title;
    public String body;
    public int starCount = 0;
    public Map<String, Boolean> stars = new HashMap<>();

    public Post() {
        // Default constructor required for calls to DataSnapshot.getValue(Post.class)
    }

    public Post(String uid, String author, String title, String body) {
        this.uid = uid;
        this.author = author;
        this.title = title;
        this.body = body;
    }

    @Exclude
    public Map<String, Object> toMap() {
        HashMap<String, Object> result = new HashMap<>();
        result.put("uid", uid);
        result.put("author", author);
        result.put("title", title);
        result.put("body", body);
        result.put("starCount", starCount);
        result.put("stars", stars);

        return result;
    }

}

Kotlin + KTX

@IgnoreExtraProperties
data class Post(
    var uid: String? = "",
    var author: String? = "",
    var title: String? = "",
    var body: String? = "",
    var starCount: Int = 0,
    var stars: MutableMap<String, Boolean> = HashMap()
) {

    @Exclude
    fun toMap(): Map<String, Any?> {
        return mapOf(
                "uid" to uid,
                "author" to author,
                "title" to title,
                "body" to body,
                "starCount" to starCount,
                "stars" to stars
        )
    }
}

पोस्ट बनाने के लिए और साथ ही साथ इसे हाल ही की गतिविधि फ़ीड और उपयोगकर्ता की गतिविधि फ़ीड को पोस्ट करने के लिए अपडेट करें, ब्लॉगिंग एप्लिकेशन इस तरह कोड का उपयोग करता है:

जावा

private void writeNewPost(String userId, String username, String title, String body) {
    // Create new post at /user-posts/$userid/$postid and at
    // /posts/$postid simultaneously
    String key = mDatabase.child("posts").push().getKey();
    Post post = new Post(userId, username, title, body);
    Map<String, Object> postValues = post.toMap();

    Map<String, Object> childUpdates = new HashMap<>();
    childUpdates.put("/posts/" + key, postValues);
    childUpdates.put("/user-posts/" + userId + "/" + key, postValues);

    mDatabase.updateChildren(childUpdates);
}

Kotlin + KTX

private fun writeNewPost(userId: String, username: String, title: String, body: String) {
    // Create new post at /user-posts/$userid/$postid and at
    // /posts/$postid simultaneously
    val key = database.child("posts").push().key
    if (key == null) {
        Log.w(TAG, "Couldn't get push key for posts")
        return
    }

    val post = Post(userId, username, title, body)
    val postValues = post.toMap()

    val childUpdates = hashMapOf<String, Any>(
            "/posts/$key" to postValues,
            "/user-posts/$userId/$key" to postValues
    )

    database.updateChildren(childUpdates)
}

यह उदाहरण push() का उपयोग करता है push() /posts/$postid getKey() पर सभी उपयोगकर्ताओं के लिए नोड वाले पोस्ट बनाने के लिए और साथ ही getKey() साथ कुंजी को पुनः प्राप्त करता है। तब उपयोगकर्ता /user-posts/$userid/$postid में उपयोगकर्ता के पदों में दूसरी प्रविष्टि बनाने के लिए कुंजी का उपयोग किया जा सकता है।

इन रास्तों का उपयोग करते हुए, आप JSON ट्री में एक ही कॉल के साथ कई स्थानों पर अपडेट अपडेट कर सकते हैं जैसे कि updateChildren() , जैसे कि यह उदाहरण दोनों स्थानों में नई पोस्ट कैसे बनाता है। इस तरह से किए गए अद्यतन अपडेट परमाणु हैं: या तो सभी अपडेट सफल होते हैं या सभी अपडेट विफल हो जाते हैं।

एक पूर्णता कॉलबैक जोड़ें

यदि आप जानना चाहते हैं कि आपका डेटा कब किया गया है, तो आप एक पूर्ण श्रोता जोड़ सकते हैं। दोनों setValue() और updateChildren() एक वैकल्पिक पूर्ण श्रोता लेते हैं, जिसे तब लिखा जाता है, जब डेटाबेस में सफलतापूर्वक लेखन हो चुका होता है। यदि कॉल विफल था, तो श्रोता को एक त्रुटि ऑब्जेक्ट पास किया जाता है जो बताता है कि विफलता क्यों हुई।

जावा

mDatabase.child("users").child(userId).setValue(user)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                // Write was successful!
                // ...
            }
        })
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                // Write failed
                // ...
            }
        });

Kotlin + KTX

database.child("users").child(userId).setValue(user)
        .addOnSuccessListener {
            // Write was successful!
            // ...
        }
        .addOnFailureListener {
            // Write failed
            // ...
        }

डेटा हटाएं

डेटा को हटाने का सबसे सरल तरीका उस डेटा के स्थान के संदर्भ में removeValue() को कॉल करना है।

आप किसी अन्य लेखन कार्रवाई जैसे कि setValue() या updateChildren() लिए मान के रूप में null निर्दिष्ट करके भी हटा सकते हैं। आप एक ही एपीआई कॉल में कई बच्चों को हटाने के लिए updateChildren() साथ इस तकनीक का उपयोग कर सकते हैं।

सुनने वालों को अलग कर लें

आपके फायरबेस डेटाबेस संदर्भ पर removeEventListener() विधि को कॉल करके कॉलबैक को हटा दिया जाता है।

यदि किसी श्रोता को एक डेटा स्थान पर कई बार जोड़ा गया है, तो इसे प्रत्येक ईवेंट के लिए कई बार कहा जाता है, और इसे पूरी तरह से निकालने के लिए आपको इसे उसी समय को अलग करना होगा।

एक माता-पिता श्रोता पर हटाने removeEventListener() कॉलिंग स्वचालित रूप से अपने बच्चे नोड पर पंजीकृत श्रोताओं को दूर नहीं करता है; removeEventListener() भी कॉलबैक को हटाने के लिए किसी भी बाल श्रोताओं को बुलाया जाना चाहिए।

लेनदेन के रूप में डेटा सहेजें

जब ऐसे डेटा के साथ काम किया जा सकता है जो समवर्ती संशोधनों, जैसे वृद्धिशील काउंटरों से दूषित हो सकते हैं, तो आप लेनदेन ऑपरेशन का उपयोग कर सकते हैं। आप इस ऑपरेशन को दो तर्क देते हैं: एक अपडेट फ़ंक्शन और एक वैकल्पिक पूर्ण कॉलबैक। अपडेट फ़ंक्शन डेटा की वर्तमान स्थिति को एक तर्क के रूप में लेता है और वह नया वांछित राज्य लौटाता है जिसे आप लिखना चाहते हैं। यदि कोई अन्य क्लाइंट आपके नए मान को सफलतापूर्वक लिखे जाने से पहले स्थान पर लिखता है, तो आपके अपडेट फ़ंक्शन को नए वर्तमान मूल्य के साथ फिर से कॉल किया जाता है, और लेखन वापस लिया जाता है।

उदाहरण के लिए, उदाहरण के लिए सामाजिक ब्लॉगिंग ऐप में, आप उपयोगकर्ताओं को स्टार और अनस्टार पोस्ट करने की अनुमति दे सकते हैं और पोस्ट के अनुसार कितने स्टार प्राप्त हुए हैं, इस पर नज़र रख सकते हैं:

जावा

private void onStarClicked(DatabaseReference postRef) {
    postRef.runTransaction(new Transaction.Handler() {
        @Override
        public Transaction.Result doTransaction(MutableData mutableData) {
            Post p = mutableData.getValue(Post.class);
            if (p == null) {
                return Transaction.success(mutableData);
            }

            if (p.stars.containsKey(getUid())) {
                // Unstar the post and remove self from stars
                p.starCount = p.starCount - 1;
                p.stars.remove(getUid());
            } else {
                // Star the post and add self to stars
                p.starCount = p.starCount + 1;
                p.stars.put(getUid(), true);
            }

            // Set value and report transaction success
            mutableData.setValue(p);
            return Transaction.success(mutableData);
        }

        @Override
        public void onComplete(DatabaseError databaseError, boolean committed,
                               DataSnapshot currentData) {
            // Transaction completed
            Log.d(TAG, "postTransaction:onComplete:" + databaseError);
        }
    });
}

Kotlin + KTX

private fun onStarClicked(postRef: DatabaseReference) {
    postRef.runTransaction(object : Transaction.Handler {
        override fun doTransaction(mutableData: MutableData): Transaction.Result {
            val p = mutableData.getValue(Post::class.java)
                    ?: return Transaction.success(mutableData)

            if (p.stars.containsKey(uid)) {
                // Unstar the post and remove self from stars
                p.starCount = p.starCount - 1
                p.stars.remove(uid)
            } else {
                // Star the post and add self to stars
                p.starCount = p.starCount + 1
                p.stars[uid] = true
            }

            // Set value and report transaction success
            mutableData.value = p
            return Transaction.success(mutableData)
        }

        override fun onComplete(
            databaseError: DatabaseError?,
            committed: Boolean,
            currentData: DataSnapshot?
        ) {
            // Transaction completed
            Log.d(TAG, "postTransaction:onComplete:" + databaseError!!)
        }
    })
}

लेन-देन का उपयोग स्टार गणना को गलत होने से रोकता है यदि कई उपयोगकर्ता एक ही पोस्ट को एक ही समय में स्टार करते हैं या क्लाइंट के पास बासी डेटा था। यदि लेन-देन अस्वीकार कर दिया जाता है, तो सर्वर क्लाइंट को वर्तमान मूल्य लौटाता है, जो अद्यतन मूल्य के साथ फिर से लेनदेन चलाता है। यह तब तक दोहराता है जब तक कि लेन-देन स्वीकार नहीं किया जाता है या बहुत सारे प्रयास किए गए हैं।

डेटा ऑफ़लाइन लिखें

यदि कोई क्लाइंट अपना नेटवर्क कनेक्शन खो देता है, तो आपका ऐप सही तरीके से काम करना जारी रखेगा।

फायरबेस डेटाबेस से जुड़ा प्रत्येक क्लाइंट किसी भी सक्रिय डेटा का अपना आंतरिक संस्करण रखता है। जब डेटा लिखा जाता है, तो इसे पहले इस स्थानीय संस्करण में लिखा जाता है। Firebase क्लाइंट तब दूरस्थ डेटाबेस सर्वर के साथ और "सर्वश्रेष्ठ प्रयास" के आधार पर अन्य क्लाइंट के साथ उस डेटा को सिंक्रनाइज़ करता है।

नतीजतन, सभी सर्वर पर स्थानीय घटनाओं को तुरंत लिखता है, इससे पहले कि सर्वर पर कोई डेटा लिखा जाए। इसका मतलब है कि नेटवर्क विलंबता या कनेक्टिविटी की परवाह किए बिना आपका ऐप उत्तरदायी है।

एक बार कनेक्टिविटी बहाल होने के बाद, आपके ऐप को घटनाओं का उपयुक्त सेट प्राप्त होता है, ताकि क्लाइंट किसी भी कस्टम कोड को लिखे बिना, वर्तमान सर्वर स्थिति के साथ सिंक हो जाए।

अगला कदम