FCM रजिस्ट्रेशन मैनेज करने के सबसे सही तरीके

अगर आपने प्रोग्राम के हिसाब से अनुरोध भेजने के लिए FCM एपीआई का इस्तेमाल किया है, तो आपको समय के साथ यह पता चल सकता है कि आपने ऐसे डिवाइसों को मैसेज भेजकर संसाधनों को बर्बाद किया है जो अब इस्तेमाल में नहीं हैं. ऐसा इसलिए, क्योंकि उनके रजिस्ट्रेशन की जानकारी पुरानी हो चुकी है. इस वजह से, Firebase कंसोल में रिपोर्ट किए गए मैसेज डिलीवरी के डेटा या BigQuery में एक्सपोर्ट किए गए डेटा पर असर पड़ सकता है. इससे डिलीवरी रेट में अचानक गिरावट दिख सकती है, लेकिन असल में ऐसा नहीं होता. इस गाइड में, कुछ ऐसे तरीकों के बारे में बताया गया है जिनका इस्तेमाल करके, मैसेज को सही लोगों को टारगेट करने और डिलीवरी की मान्य रिपोर्टिंग को पक्का किया जा सकता है.

पुराने और समयसीमा खत्म हो चुके रजिस्ट्रेशन

पुराने रजिस्ट्रेशन, उन इनऐक्टिव डिवाइसों से जुड़े होते हैं जो एक महीने से ज़्यादा समय से FCM से कनेक्ट नहीं हुए हैं. समय बीतने के साथ-साथ, डिवाइस के FCM से फिर कभी कनेक्ट न होने की संभावना बढ़ती जाती है. इन पुराने रजिस्ट्रेशन के लिए, मैसेज भेजने और विषय के हिसाब से मैसेज पाने की सुविधा कभी भी उपलब्ध नहीं कराई जाएगी.

किसी रजिस्ट्रेशन के पुराने होने की कई वजहें हो सकती हैं. उदाहरण के लिए, जिस डिवाइस से रजिस्ट्रेशन किया गया है वह खो गया हो, खराब हो गया हो या उसे स्टोरेज में रख दिया गया हो और उपयोगकर्ता उसे भूल गया हो.

Android के लिए, अगर कोई रजिस्ट्रेशन 270 दिनों तक चालू नहीं रहता है, तो FCM उसे एक्सपायर मान लेता है और उसे मिटा देता है. रजिस्ट्रेशन की समयसीमा खत्म होने के बाद, FCM इसे अमान्य के तौर पर मार्क करता है और इस पर भेजे जाने वाले ईमेल अस्वीकार कर देता है. ध्यान दें कि Firebase इंस्टॉलेशन आईडी (एफआईडी) को FCM नहीं, बल्कि Firebase Installations service (FIS) मैनेज करती है. अगर कोई डिवाइस फिर से कनेक्ट होता है और ऐप्लिकेशन को उसके रजिस्ट्रेशन के डेटा को मिटाने के बाद खोला जाता है, तो क्लाइंट ऐप्लिकेशन, FCM के साथ फिर से रजिस्टर करता है. इसके लिए, वह FIS से मिले FID का इस्तेमाल करता है. ध्यान दें कि एफआईडी बदल सकता है; एफआईडी फिर से कब जारी किए जाते हैं, इस बारे में जानने के लिए Firebase इंस्टॉलेशन मैनेज करें लेख पढ़ें.

iOS जैसे अन्य प्लैटफ़ॉर्म के लिए, FCM पुश सेवा (जैसे, APNs) पर निर्भर करता है. इसमें 270 दिनों तक ऐप्लिकेशन का इस्तेमाल न करने पर, सदस्यता खत्म होने की सुविधा उपलब्ध नहीं है. हमारा सुझाव है कि आप रजिस्ट्रेशन की जानकारी को अपडेट रखें और पुराने रजिस्ट्रेशन हटाएं.

बुनियादी सबसे सही तरीके

ऐसे किसी भी ऐप्लिकेशन में आपको कुछ बुनियादी तरीकों का पालन करना चाहिए जो प्रोग्राम के हिसाब से अनुरोध भेजने के लिए, FCM एपीआई का इस्तेमाल करता है. सबसे सही तरीके ये हैं:

  • FCM से Firebase इंस्टॉलेशन आईडी (एफआईडी) पाएं और उन्हें अपने ऐप्लिकेशन सर्वर पर सेव करें. सर्वर की एक अहम भूमिका यह है कि वह हर क्लाइंट के रजिस्टर किए गए FID को ट्रैक करे और चालू FID की अपडेट की गई सूची को बनाए रखे. हमारा सुझाव है कि आप अपने डेटाबेस में रजिस्ट्रेशन का टाइमस्टैंप लागू करें. साथ ही, जब भी कोई रजिस्ट्रेशन अपलोड किया जाए, तब इसे अपडेट करें.
  • रजिस्ट्रेशन की जानकारी को अप-टू-डेट रखें और पुराने रजिस्ट्रेशन हटाएं. FCM जिन रजिस्ट्रेशन को अब मान्य नहीं मानता उन्हें हटाने के अलावा, आपको ऐसे अन्य संकेतों पर भी नज़र रखनी चाहिए जिनसे पता चलता है कि रजिस्ट्रेशन पुराने हो गए हैं. साथ ही, उन्हें पहले से ही हटा देना चाहिए. इस गाइड में, ऐसा करने के कुछ विकल्पों के बारे में बताया गया है.

Firebase इंस्टॉलेशन आईडी को वापस पाना और सेव करना

जब आपका ऐप्लिकेशन पहली बार शुरू होता है, तब FCM SDK टूल, ऐप्लिकेशन इंस्टेंस को FCM के साथ रजिस्टर करता है. साथ ही, Firebase इंस्टॉलेशन आईडी (FID) दिखाता है. यह वह आइडेंटिफ़ायर है जिसे आपको एपीआई से भेजे जाने वाले टारगेट किए गए अनुरोधों में शामिल करना होगा. इसके अलावा, इसका इस्तेमाल विषय की सदस्यता के लिए भी किया जा सकता है.

हमारा सुझाव है कि जब भी FID अपलोड किया जाए, तो उसे अपने ऐप्लिकेशन सर्वर पर टाइमस्टैंप के साथ सेव करें. हर अपलोड अनुरोध पर टाइमस्टैंप अपडेट करने से, आपके सर्वर को यह पता चलता है कि ऐप्लिकेशन इंस्टेंस को पिछली बार कब खोला गया था और FCM बैकएंड के साथ कब सिंक किया गया था.

अपने-आप चालू होने की सुविधा चालू है या बंद है (इसमें सुविधा काम न करने की स्थिति भी शामिल है), इसके आधार पर आपको रजिस्ट्रेशन और अपडेट को इस तरह मैनेज करना चाहिए:

  • (सुझाया गया) जब ऑटो-इनिशियलाइज़ेशन की सुविधा चालू होती है, तब: एसडीके, रजिस्ट्रेशन को अपने-आप अपडेट करता रहता है और बदलावों पर नज़र रखता है. ऐप्लिकेशन शुरू होने पर, रूटीन सिंक के दौरान onRegistered() कॉलबैक को नियमित तौर पर कॉल किया जाता है. साथ ही, जब FID में बदलाव होते हैं, तब भी इसे कॉल किया जाता है. अपने सर्वर पर FID अपलोड करने और मौजूदा टाइमस्टैंप सेव करने के लिए, इस कॉलबैक को लागू करें.
  • अपने-आप शुरू होने की सुविधा बंद होने पर: onRegistered() कॉलबैक, शुरू होने पर अपने-आप शुरू नहीं होगा. रजिस्ट्रेशन को ट्रैक करने और उन्हें अपडेट रखने के लिए, ऐप्लिकेशन के स्टार्टअप पर register() को कॉल करें. उदाहरण के लिए, Android पर मुख्य गतिविधि के onCreate() में. कॉल पूरा होने पर, FCMरजिस्ट्रेशन की प्रोसेस शुरू हो जाती है. इसके लिए, FID का इस्तेमाल किया जाता है. साथ ही, इसे आपके onRegistered() कॉलबैक पर डिलीवर किया जाता है. इससे आपका ऐप्लिकेशन, FID को अपलोड कर पाता है और आपके सर्वर पर टाइमस्टैंप को अपडेट कर पाता है.

उदाहरण: Cloud Firestore में स्टोर के आईडी और टाइमस्टैंप सेव करना

उदाहरण के लिए, Cloud Firestore का इस्तेमाल करके, fcmRegistrations नाम के कलेक्शन में FID सेव किए जा सकते हैं. संग्रह में मौजूद हर दस्तावेज़ आईडी, किसी यूज़र आईडी से जुड़ा होता है. साथ ही, दस्तावेज़ में मौजूदा FID और उसके अपडेट होने का टाइमस्टैंप सेव होता है. set फ़ंक्शन का इस्तेमाल करें. यहां Kotlin का उदाहरण दिया गया है:

private fun sendRegistrationToServer(installationId: String?) {
    // If you're running your own server, call API to send registration details and today's date for the user

    // Example shown uses Firestore
    // Add FID and timestamp to Firestore for this user
    val deviceFid = hashMapOf(
        "installationId" to installationId,
        "timestamp" to FieldValue.serverTimestamp(),
    )
    // Get user ID from Firebase Auth or your own server
    Firebase.firestore.collection("fcmRegistrations").document("myuserid")
        .set(deviceFid)
}

जब भी Firebase इंस्टॉलेशन आईडी रजिस्टर हो जाता है या अपडेट हो जाता है, तब onRegistered() कॉलबैक शुरू हो जाता है. आपको इस कॉलबैक को लागू करना चाहिए, ताकि FID को अपलोड किया जा सके और टाइमस्टैंप को अपडेट किया जा सके:

override fun onRegistered(installationId: String) {
    Log.d(TAG, "Registered installation ID: $installationId")

    // Send the Firebase Installation ID (FID) to your app server. Your app
    // server should save the FID and update the timestamp upon receipt.
    sendRegistrationToServer(installationId)
}

जिन इंस्टेंस में अपने-आप शुरू होने की सुविधा बंद है उनमें ऐप्लिकेशन के स्टार्टअप पर register() को कॉल करें.उदाहरण के लिए, onCreate() में. इससे रजिस्ट्रेशन फ़्लो और onRegistered() के ज़रिए FID डिलीवरी ट्रिगर हो जाएगी:

// Trigger manual registration if auto-initialization is turned off.
FirebaseMessaging.getInstance().register()
    .addOnCompleteListener(this) { task ->
        if (task.isSuccessful) {
            // The registration callback onRegistered() will be invoked with the current FID.
        } else {
            Log.w(TAG, "Failed to register with Firebase Cloud Messaging", task.exception)
        }
    }

रजिस्ट्रेशन की जानकारी को अपडेट रखना और पुराने रजिस्ट्रेशन हटाना

यह पता लगाना हमेशा आसान नहीं होता कि कोई रजिस्ट्रेशन नया है या पुराना. सभी मामलों को कवर करने के लिए, आपको एक थ्रेशोल्ड तय करना चाहिए. इससे यह तय किया जा सकेगा कि रजिस्ट्रेशन को कब पुराना माना जाए. डिफ़ॉल्ट रूप से, FCM किसी रजिस्ट्रेशन को पुराना मानता है. ऐसा तब होता है, जब ऐप्लिकेशन का इंस्टेंस एक महीने तक कनेक्ट न हो. अगर किसी डिवाइस का रजिस्ट्रेशन एक महीने से ज़्यादा पुराना है, तो हो सकता है कि वह डिवाइस इस्तेमाल न किया जा रहा हो. अगर डिवाइस इस्तेमाल किया जा रहा होता, तो उसका रजिस्ट्रेशन अपने-आप रीफ़्रेश हो जाता.

इस्तेमाल के आधार पर, एक महीने की अवधि बहुत कम या बहुत ज़्यादा हो सकती है. इसलिए, यह तय करना आपका काम है कि आपके लिए कौनसी शर्तें सही हैं.

FCM बैकएंड से मिले अमान्य जवाबों का पता लगाना

यह पक्का करें कि FCM से मिले अमान्य जवाबों का पता लगाया जा सके. साथ ही, अपने सिस्टम से उन सभी रजिस्ट्रेशन को मिटाकर जवाब दें जो अमान्य हैं या जिनकी समयसीमा खत्म हो गई है. एचटीटीपी v1 एपीआई के साथ, गड़बड़ी के ये मैसेज यह दिखा सकते हैं कि ईमेल भेजने के आपके अनुरोध में, अमान्य या समयसीमा खत्म हो चुके रजिस्ट्रेशन को टारगेट किया गया है:

  • UNREGISTERED (एचटीटीपी 404)
  • INVALID_ARGUMENT (एचटीटीपी 400)

अगर आपको लगता है कि मैसेज का पेलोड मान्य है और आपको टारगेट किए गए रजिस्ट्रेशन के लिए इनमें से कोई एक जवाब मिलता है, तो इस रजिस्ट्रेशन का रिकॉर्ड मिटाना सुरक्षित है. ऐसा इसलिए, क्योंकि यह रजिस्ट्रेशन कभी मान्य नहीं होगा. उदाहरण के लिए, Cloud Firestore से अमान्य रजिस्ट्रेशन मिटाने के लिए, इस तरह के फ़ंक्शन को डिप्लॉय और चलाया जा सकता है:

        // Firebase Installation ID comes from the client FCM SDKs
        const firebaseInstallationId = 'YOUR_FIREBASE_INSTALLATION_ID';

        const message = {
            data: {
                // Information you want to send inside of notification
            },
            fid: firebaseInstallationId
        };

        // Send message to device with provided Firebase Installation ID
        getMessaging().send(message)
        .then((response) => {
            // Response is a message ID string.
        })
        .catch((error) => {
            // Delete registration for user if error code is UNREGISTERED or INVALID_ARGUMENT.
            if (error.errorCode == "messaging/registration-token-not-registered") {
                // If you're running your own server, call API to delete the registration for the user
                // Example shown uses Firestore
                // Get user ID from Firebase Auth or your own server
                Firebase.firestore.collection("fcmRegistrations").document(user.uid).delete()
            }
        });

अगर Android डिवाइस के लिए रजिस्ट्रेशन की समयसीमा 270 दिनों तक कोई गतिविधि न होने के बाद खत्म हो जाती है या अगर कोई क्लाइंट साफ़ तौर पर अनरजिस्टर करता है, तो FCM अमान्य जवाब दिखाता है. अगर आपको अपनी परिभाषाओं के हिसाब से, डेटा के अपडेट न होने की स्थिति को ज़्यादा सटीक तरीके से ट्रैक करना है, तो अपडेट न किए गए रजिस्ट्रेशन हटाएं.

नियमित तौर पर रजिस्ट्रेशन अपडेट करना

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

FID एपीआई का इस्तेमाल करने वाले क्लाइंट ऐप्लिकेशन के लिए, आपको रजिस्ट्रेशन वापस पाने या उन्हें रीफ़्रेश करने के लिए, क्लाइंट ऐप्लिकेशन में समय-समय पर बैकग्राउंड जॉब शेड्यूल करने की ज़रूरत नहीं है. एसडीके, अपने-आप शुरू होने की सुविधा के तहत रीफ़्रेश होने की प्रोसेस को अपने-आप मैनेज करता है. साथ ही, ऐप्लिकेशन शुरू होने के दौरान नियमित रूप से सिंक होने पर, आपके onRegistered() कॉलबैक को सही मौजूदा FID डिलीवर करता है.

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

  • अपने-आप शुरू होने की सुविधा चालू है: एसडीके यह अपने-आप पक्का करता है कि ऐप्लिकेशन शुरू होने के दौरान, रूटीन सिंक पर आपके सर्वर को नया FID भेजा जाए.
  • ऑटो-इनिशियलाइज़ेशन की सुविधा बंद है या काम नहीं कर रही है: ऐप्लिकेशन के शुरू होने पर register() को कॉल करें. उदाहरण के लिए, Android पर, मुख्य ऐक्टिविटी के onCreate() में. इससे रजिस्ट्रेशन सीक्वेंस को फ़ोर्स किया जा सकेगा और आपके onRegistered() कॉलबैक को FID डिलीवर किया जा सकेगा.

इन रणनीतियों से यह पक्का होता है कि आपके सर्वर के पास हमेशा चालू FID का नया वर्शन हो. साथ ही, ये अपलोड न होने की समस्या को अपने-आप ठीक कर सकती हैं. इससे ऐप्लिकेशन को ज़्यादा सुरक्षित बनाया जा सकता है.

रजिस्ट्रेशन टोकन के लिए इस्तेमाल किए जाने वाले पुराने एपीआई

लेगसी रजिस्ट्रेशन टोकन का इस्तेमाल करने पर, क्लाइंट एसडीके नियमित सिंक पर रीफ़्रेश को अपने-आप मैनेज नहीं करता. इसलिए, हमारा सुझाव है कि आप समय-समय पर अपने सर्वर पर सभी रजिस्ट्रेशन टोकन फिर से पाएं और उन्हें अपडेट करें. इसके लिए, आपको:

  • अपने क्लाइंट ऐप्लिकेशन में ऐप्लिकेशन लॉजिक जोड़ें. इससे सही एपीआई कॉल (जैसे कि Apple प्लैटफ़ॉर्म के लिए token(completion): या Android के लिए getToken()) का इस्तेमाल करके, मौजूदा टोकन को वापस पाया जा सकेगा. इसके बाद, मौजूदा टोकन को अपने ऐप्लिकेशन सर्वर पर भेजें, ताकि उसे टाइमस्टैंप के साथ सेव किया जा सके. यह हर महीने चलने वाला ऐसा जॉब हो सकता है जिसे सभी क्लाइंट या टोकन के लिए कॉन्फ़िगर किया गया हो.
  • टोकन के टाइमस्टैंप को नियमित अंतराल पर अपडेट करने के लिए, सर्वर लॉजिक जोड़ें. भले ही, टोकन बदला गया हो या नहीं.

WorkManager का इस्तेमाल करके लेगसी टोकन अपडेट करने के लिए, Android लॉजिक का उदाहरण देखने के लिए, Firebase ब्लॉग पर Cloud Messaging टोकन मैनेज करना लेख पढ़ें.

आप जिस भी समय के हिसाब से टोकन अपडेट करते हैं, यह पक्का करें कि टोकन को समय-समय पर अपडेट किया जाए. हर महीने में एक बार अपडेट करने से, बैटरी पर पड़ने वाले असर और इनऐक्टिव रजिस्ट्रेशन टोकन का पता लगाने के बीच सही संतुलन बना रहता है. इस तरह से रीफ़्रेश करने पर, यह भी पक्का किया जा सकेगा कि अगर कोई डिवाइस बंद हो जाता है, तो फिर से चालू होने पर वह अपना रजिस्ट्रेशन रीफ़्रेश कर लेगा. हर हफ़्ते से ज़्यादा बार रीफ़्रेश करने से कोई फ़ायदा नहीं होता.

पुराने रजिस्ट्रेशन हटाना

किसी डिवाइस को मैसेज भेजने से पहले, पक्का करें कि डिवाइस के रजिस्ट्रेशन का टाइमस्टैंप, स्टेलनेस विंडो की अवधि के अंदर हो. उदाहरण के लिए, Cloud Functions for Firebase को लागू करके, हर दिन यह जांच की जा सकती है कि टाइमस्टैंप, तय की गई स्टेलनेस विंडो की अवधि के अंदर है या नहीं. जैसे, const EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 30;. इसके बाद, पुराने रजिस्ट्रेशन हटाए जा सकते हैं:

exports.pruneRegistrations = functions.pubsub.schedule('every 24 hours').onRun(async (context) => {
  // Get all documents where the timestamp exceeds is not within the past month
  const staleRegistrationsResult = await admin.firestore().collection('fcmRegistrations')
      .where("timestamp", "<", Date.now() - EXPIRATION_TIME)
      .get();
  // Delete devices with stale registrations
  staleRegistrationsResult.forEach(function(doc) { doc.ref.delete(); });
});
exports.pruneTokens = functions.pubsub.schedule('every 24 hours').onRun(async (context) => { // Get all documents where the timestamp exceeds is not within the past month const staleTokensResult = await admin.firestore().collection('fcmTokens') .where("timestamp", "<", Date.now() - EXPIRATION_TIME) .get(); // Delete devices with stale tokens staleTokensResult.forEach(function(doc) { doc.ref.delete(); }); });

विषयों के लिए, पुराने रजिस्ट्रेशन की सदस्यता छोड़ना

अगर विषयों का इस्तेमाल किया जाता है, तो आपको उन विषयों के लिए पुराने रजिस्ट्रेशन की सदस्यता भी छोड़नी पड़ सकती है जिनके लिए उन्होंने सदस्यता ली है. इसके लिए, ये दो चरण पूरे करें:

  1. जब भी Firebase इंस्टॉलेशन आईडी (एफ़आईडी) बदलता है, तब आपके ऐप्लिकेशन को विषयों की सदस्यता फिर से लेनी चाहिए. इससे, किसी ऐप्लिकेशन के फिर से चालू होने पर, सदस्यताएं अपने-आप दिखने लगती हैं.
  2. अगर कोई ऐप्लिकेशन इंस्टेंस एक महीने तक इस्तेमाल नहीं किया जाता है (या आपकी तय की गई अवधि तक इस्तेमाल नहीं किया जाता है), तो आपको उसे विषयों से अनसब्सक्राइब करना चाहिए. इसके लिए, Firebase Admin SDK का इस्तेमाल करें. इससे FCM बैकएंड से, Firebase इंस्टॉलेशन आईडी को विषय से मैप करने की सुविधा मिट जाएगी.

इन दो चरणों का फ़ायदा यह है कि आपके फ़ैन-आउट तेज़ी से होंगे, क्योंकि फ़ैन-आउट करने के लिए कम पुरानी जानकारी वाले रजिस्ट्रेशन हैं. साथ ही, आपके ऐप्लिकेशन के पुरानी जानकारी वाले इंस्टेंस फिर से ऐक्टिव होने पर, वे अपने-आप फिर से सदस्यता ले लेंगे.

डिलीवरी की सफलता का आकलन करना

मैसेज डिलीवरी की सबसे सटीक जानकारी पाने के लिए, सिर्फ़ उन ऐप्लिकेशन इंस्टेंस को मैसेज भेजें जिनका इस्तेमाल किया जा रहा है. अगर आपको ऐसे विषयों पर नियमित रूप से मैसेज भेजने हैं जिनके लिए बड़ी संख्या में लोगों ने सदस्यता ली है, तो यह जानकारी आपके लिए खास तौर पर अहम है. अगर इन सदस्यों में से कुछ सदस्य असल में निष्क्रिय हैं, तो समय के साथ-साथ मैसेज डिलीवर होने से जुड़े आंकड़ों पर इसका काफ़ी असर पड़ सकता है.

किसी ऐप्लिकेशन इंस्टेंस को मैसेज टारगेट करने से पहले, इन बातों का ध्यान रखें:

  • क्या Google Analytics, BigQuery में कैप्चर किया गया डेटा या अन्य ट्रैकिंग सिग्नल से पता चलता है कि रजिस्ट्रेशन चालू है?
  • क्या डिलीवरी करने की पिछली कोशिशें लगातार कुछ समय से पूरी नहीं हो पा रही हैं?
  • क्या पिछले महीने आपके सर्वर पर Firebase इंस्टॉलेशन आईडी अपडेट किया गया था?
  • क्या Android डिवाइसों के लिए, FCM Data API, droppedDeviceInactive की वजह से मैसेज डिलीवर न होने की ज़्यादा दर रिपोर्ट करता है?

डिलीवरी के बारे में ज़्यादा जानने के लिए, मैसेज की डिलीवरी के बारे में जानकारी लेख पढ़ें.