Firebase एम्युलेटर सुइट का इस्तेमाल करके, आपके Flutter ऐप्लिकेशन के लिए लोकल डेवलपमेंट

1. शुरू करने से पहले

इस कोडलैब में, आपको लोकल डेवलपमेंट के दौरान Flutter के साथ Firebase Emulator Suite का इस्तेमाल करने का तरीका बताया जाएगा. आपको Emulator Suite के ज़रिए ईमेल और पासवर्ड की मदद से पुष्टि करने की सुविधा का इस्तेमाल करने का तरीका बताया जाएगा. साथ ही, Firestore Emulator में डेटा पढ़ने और लिखने का तरीका भी बताया जाएगा. आखिर में, आपको इम्यूलेटर से डेटा इंपोर्ट और एक्सपोर्ट करने का तरीका बताया जाएगा. इससे, डेवलपमेंट पर वापस आने पर हर बार एक ही फ़र्ज़ी डेटा का इस्तेमाल किया जा सकेगा.

ज़रूरी शर्तें

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

आपको Firebase का कुछ अनुभव होना चाहिए. हालांकि, अगर आपने कभी किसी Flutter प्रोजेक्ट में Firebase नहीं जोड़ा है, तो भी कोई समस्या नहीं है. अगर आपको Firebase कंसोल के बारे में जानकारी नहीं है या आपने Firebase का इस्तेमाल पहले कभी नहीं किया है, तो पहले इन लिंक पर जाएं:

आपको क्या बनाना है

इस कोडलैब में, जर्नलिंग ऐप्लिकेशन बनाने के बारे में बताया गया है. ऐप्लिकेशन में एक लॉगिन स्क्रीन होगी. साथ ही, एक ऐसी स्क्रीन होगी जिस पर पिछली जर्नल एंट्री पढ़ी जा सकेंगी और नई एंट्री बनाई जा सकेंगी.

cd5c4753bbee8af.png 8cb4d21f656540bf.png

आपको क्या सीखने को मिलेगा

आपको Firebase का इस्तेमाल शुरू करने का तरीका बताया जाएगा. साथ ही, Firebase Emulator Suite को अपने Flutter डेवलपमेंट वर्कफ़्लो में इंटिग्रेट करने और इस्तेमाल करने का तरीका बताया जाएगा. इन Firebase विषयों के बारे में बताया जाएगा:

ध्यान दें कि इन विषयों को सिर्फ़ उतना ही कवर किया गया है जितना Firebase Emulator Suite के बारे में बताने के लिए ज़रूरी है. इस कोडलैब में, Firebase प्रोजेक्ट को अपने Flutter ऐप्लिकेशन में जोड़ने और Firebase Emulator Suite का इस्तेमाल करके डेवलपमेंट करने पर फ़ोकस किया गया है. Firebase Authentication या Firestore के बारे में ज़्यादा जानकारी नहीं दी जाएगी. अगर आपको इन विषयों के बारे में जानकारी नहीं है, तो हमारा सुझाव है कि आप Flutter के लिए Firebase के बारे में जानकारी देने वाले कोडलैब से शुरुआत करें.

आपको इनकी ज़रूरत होगी

  • Flutter के बारे में बुनियादी जानकारी और SDK टूल इंस्टॉल किया गया हो
  • Intellij JetBrains या VS Code टेक्स्ट एडिटर
  • Google Chrome ब्राउज़र या Flutter के लिए, डेवलपमेंट का कोई अन्य पसंदीदा टारगेट. इस कोडलैब में कुछ टर्मिनल कमांड से यह माना जाएगा कि आपने Chrome पर अपना ऐप्लिकेशन चलाया है)

2. Firebase प्रोजेक्ट बनाना और उसे सेट अप करना

आपको सबसे पहले, Firebase के वेब कंसोल में Firebase प्रोजेक्ट बनाना होगा. इस कोडलैब का ज़्यादातर हिस्सा Emulator Suite पर फ़ोकस करेगा. यह स्थानीय तौर पर चल रहे यूज़र इंटरफ़ेस (यूआई) का इस्तेमाल करता है. हालांकि, आपको सबसे पहले पूरा Firebase प्रोजेक्ट सेट अप करना होगा.

Firebase प्रोजेक्ट बनाना

  1. अपने Google खाते का इस्तेमाल करके, Firebase कंसोल में साइन इन करें.
  2. नया प्रोजेक्ट बनाने के लिए, बटन पर क्लिक करें. इसके बाद, प्रोजेक्ट का नाम डालें. उदाहरण के लिए, Firebase-Flutter-Codelab.
  3. जारी रखें पर क्लिक करें.
  4. अगर आपसे कहा जाए, तो Firebase की शर्तें पढ़ें और स्वीकार करें. इसके बाद, जारी रखें पर क्लिक करें.
  5. (ज़रूरी नहीं) Firebase कंसोल में एआई की मदद पाने की सुविधा चालू करें. इसे "Firebase में Gemini" कहा जाता है.
  6. इस कोडलैब के लिए, आपको Google Analytics की ज़रूरत नहीं है. इसलिए, Google Analytics के विकल्प को टॉगल करके बंद करें.
  7. प्रोजेक्ट बनाएं पर क्लिक करें. इसके बाद, प्रोजेक्ट के प्रोविज़न होने का इंतज़ार करें. इसके बाद, जारी रखें पर क्लिक करें.

Firebase प्रोजेक्ट के बारे में ज़्यादा जानने के लिए, Firebase प्रोजेक्ट के बारे में जानकारी लेख पढ़ें.

Firebase प्रॉडक्ट सेट अप करना

आपके बनाए जा रहे ऐप्लिकेशन में, Flutter ऐप्लिकेशन के लिए उपलब्ध दो Firebase प्रॉडक्ट का इस्तेमाल किया जाता है:

  • Firebase Authentication की मदद से, उपयोगकर्ताओं को आपके ऐप्लिकेशन में साइन इन करने की अनुमति दें.
  • क्लाउड पर स्ट्रक्चर्ड डेटा सेव करने के लिए Cloud Firestore का इस्तेमाल करें. साथ ही, डेटा में बदलाव होने पर तुरंत सूचना पाएं.

इन दोनों प्रॉडक्ट को खास कॉन्फ़िगरेशन की ज़रूरत होती है. इसके अलावा, इन्हें Firebase कंसोल का इस्तेमाल करके चालू करना होता है.

Cloud Firestore चालू करना

Flutter ऐप्लिकेशन, डायरी एंट्री सेव करने के लिए Cloud Firestore का इस्तेमाल करता है.

Cloud Firestore चालू करें:

  1. Firebase कंसोल के बनाएं सेक्शन में जाकर, Cloud Firestore पर क्लिक करें.
  2. डेटाबेस बनाएं पर क्लिक करें. 99e8429832d23fa3.png
  3. टेस्ट मोड में शुरू करें विकल्प चुनें. सुरक्षा नियमों के बारे में डिसक्लेमर पढ़ें. टेस्ट मोड यह पक्का करता है कि डेवलपमेंट के दौरान, डेटाबेस में आसानी से लिखा जा सके. आगे बढ़ें पर क्लिक करें. 6be00e26c72ea032.png
  4. अपने डेटाबेस के लिए जगह चुनें. हालांकि, डिफ़ॉल्ट जगह का इस्तेमाल भी किया जा सकता है. ध्यान दें कि इस जगह को बाद में बदला नहीं जा सकता. 278656eefcfb0216.png
  5. चालू करें पर क्लिक करें.

3. Flutter ऐप्लिकेशन सेट अप करना

शुरू करने से पहले, आपको स्टार्टर कोड डाउनलोड करना होगा. साथ ही, Firebase CLI इंस्टॉल करना होगा.

स्टार्टर कोड पाना

कमांड लाइन से GitHub रिपॉज़िटरी का क्लोन बनाएं:

git clone https://github.com/flutter/codelabs.git flutter-codelabs

इसके अलावा, अगर आपने GitHub का cli टूल इंस्टॉल किया है, तो:

gh repo clone flutter/codelabs flutter-codelabs

सैंपल कोड को flutter-codelabs डायरेक्ट्री में क्लोन किया जाना चाहिए. इसमें कोडलैब के कलेक्शन का कोड होता है. इस कोडलैब का कोड flutter-codelabs/firebase-emulator-suite में है.

flutter-codelabs/firebase-emulator-suite के तहत डायरेक्ट्री स्ट्रक्चर में दो Flutter प्रोजेक्ट शामिल हैं. इसे complete कहा जाता है. अगर आपको आगे बढ़ना है या अपने कोड को क्रॉस-रेफ़रंस करना है, तो इसे देखें. दूसरे प्रोजेक्ट का नाम start है.

आपको जिस कोड से शुरुआत करनी है वह flutter-codelabs/firebase-emulator-suite/start डायरेक्ट्री में है. उस डायरेक्ट्री को अपने पसंदीदा IDE में खोलें या इंपोर्ट करें.

cd flutter-codelabs/firebase-emulator-suite/start

Firebase CLI इंस्टॉल करना

Firebase CLI, Firebase प्रोजेक्ट मैनेज करने के लिए टूल उपलब्ध कराती है. Emulator Suite का इस्तेमाल करने के लिए, सीएलआई की ज़रूरत होती है. इसलिए, आपको इसे इंस्टॉल करना होगा.

सीएलआई को इंस्टॉल करने के कई तरीके हैं. अगर MacOS या Linux का इस्तेमाल किया जा रहा है, तो सबसे आसान तरीका यह है कि अपने टर्मिनल से यह निर्देश चलाएं:

curl -sL https://firebase.tools | bash

CLI इंस्टॉल करने के बाद, आपको Firebase से पुष्टि करनी होगी.

  1. अपने Google खाते का इस्तेमाल करके Firebase में लॉग इन करें. इसके लिए, यह कमांड चलाएं:
firebase login
  1. इस कमांड से, आपकी लोकल मशीन Firebase से कनेक्ट हो जाती है. साथ ही, आपको अपने Firebase प्रोजेक्ट का ऐक्सेस मिल जाता है.
  1. जांच करें कि सीएलआई सही तरीके से इंस्टॉल हो गया हो और उसके पास आपके खाते का ऐक्सेस हो. इसके लिए, अपने Firebase प्रोजेक्ट की सूची बनाएं. यह कमांड चलाएं:
firebase projects:list
  1. दिखाई गई सूची में मौजूद Firebase प्रोजेक्ट, Firebase कंसोल में मौजूद Firebase प्रोजेक्ट के बराबर होने चाहिए. आपको कम से कम firebase-flutter-codelab दिखना चाहिए.

FlutterFire सीएलआई इंस्टॉल करना

FlutterFire CLI, Firebase CLI पर आधारित है. इससे Firebase प्रोजेक्ट को अपने Flutter ऐप्लिकेशन के साथ इंटिग्रेट करना आसान हो जाता है.

सबसे पहले, सीएलआई इंस्टॉल करें:

dart pub global activate flutterfire_cli

पक्का करें कि सीएलआई इंस्टॉल हो गया हो. Flutter प्रोजेक्ट डायरेक्ट्री में यह कमांड चलाएं. साथ ही, पक्का करें कि सीएलआई, सहायता मेन्यू दिखाता हो.

flutterfire --help

Firebase CLI और FlutterFire CLI का इस्तेमाल करके, अपने Firebase प्रोजेक्ट को Flutter ऐप्लिकेशन में जोड़ें

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

सबसे पहले, Firebase को सेट अप करें. इसके लिए, यह कमांड चलाएं:

firebase init

इस कमांड से, आपको प्रोजेक्ट सेट अप करने के लिए ज़रूरी सवालों के जवाब देने होंगे. इन स्क्रीनशॉट में फ़्लो दिखाया गया है:

  1. सुविधाएं चुनने के लिए कहा जाने पर, "Firestore" और "Emulators" को चुनें. (इसमें पुष्टि करने का कोई विकल्प नहीं है, क्योंकि यह ऐसे कॉन्फ़िगरेशन का इस्तेमाल करता है जिसे आपके Flutter प्रोजेक्ट की फ़ाइलों से बदला नहीं जा सकता.) fe6401d769be8f53.png
  2. इसके बाद, जब आपसे पूछा जाए, तो "किसी मौजूदा प्रोजेक्ट का इस्तेमाल करें" चुनें.

f11dcab439e6ac1e.png

  1. अब, वह प्रोजेक्ट चुनें जिसे आपने पिछले चरण में बनाया था: flutter-firebase-codelab.

3bdc0c6934991c25.png

  1. इसके बाद, आपसे जनरेट होने वाली फ़ाइलों के नाम रखने के बारे में एक के बाद एक कई सवाल पूछे जाएंगे. मेरा सुझाव है कि हर सवाल के लिए डिफ़ॉल्ट विकल्प चुनने के लिए, "enter" दबाएं. 9bfa2d507e199c59.png
  2. आखिर में, आपको एम्युलेटर कॉन्फ़िगर करने होंगे. सूची से Firestore और Authentication चुनें. इसके बाद, हर एम्युलेटर के लिए इस्तेमाल किए जाने वाले पोर्ट के बारे में पूछे गए हर सवाल के लिए, "Enter" दबाएं. जब आपसे पूछा जाए कि क्या आपको Emulator UI का इस्तेमाल करना है, तो आपको डिफ़ॉल्ट रूप से 'हां' चुनना चाहिए.

प्रोसेस पूरी होने के बाद, आपको ऐसा आउटपुट दिखेगा जैसा इस स्क्रीनशॉट में दिखाया गया है.

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

8544e41037637b07.png

FlutterFire को कॉन्फ़िगर करना

इसके बाद, FlutterFire का इस्तेमाल करके, अपने Flutter ऐप्लिकेशन में Firebase का इस्तेमाल करने के लिए ज़रूरी डार्ट कोड जनरेट किया जा सकता है.

flutterfire configure

इस कमांड को चलाने पर, आपसे पूछा जाएगा कि आपको कौनसा Firebase प्रोजेक्ट इस्तेमाल करना है और आपको किन प्लैटफ़ॉर्म को सेट अप करना है. इस कोडलैब में दिए गए उदाहरणों में Flutter Web का इस्तेमाल किया गया है. हालांकि, सभी विकल्पों का इस्तेमाल करने के लिए, अपना Firebase प्रोजेक्ट सेट अप किया जा सकता है.

यहां दिए गए स्क्रीनशॉट में, वे प्रॉम्प्ट दिखाए गए हैं जिनके जवाब आपको देने होंगे.

619b7aca6dc15472.png 301c9534f594f472.png

इस स्क्रीनशॉट में, प्रोसेस के आखिर में मिलने वाला आउटपुट दिखाया गया है. अगर आपको Firebase के बारे में जानकारी है, तो आपको पता होगा कि कंसोल में ऐप्लिकेशन बनाने की ज़रूरत नहीं पड़ी. FlutterFire CLI ने यह काम आपके लिए किया.

12199a85ade30459.png

Flutter ऐप्लिकेशन में Firebase पैकेज जोड़ना

सेटअप का आखिरी चरण यह है कि अपने Flutter प्रोजेक्ट में, काम के Firebase पैकेज जोड़ें. टर्मिनल में, पक्का करें कि आप flutter-codelabs/firebase-emulator-suite/start पर Flutter प्रोजेक्ट के रूट में हों. इसके बाद, ये तीन कमांड चलाएं:

flutter pub add firebase_core
flutter pub add firebase_auth
flutter pub add cloud_firestore

इस ऐप्लिकेशन में सिर्फ़ इन पैकेज का इस्तेमाल किया जाएगा.

4. Firebase इम्यूलेटर चालू करना

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

सबसे पहले, Firebase को शुरू करने वाला कोड और एम्युलेटर सेटअप कोड को main.dart. में मौजूद main फ़ंक्शन में जोड़ें

main.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

import 'app_state.dart';
import 'firebase_options.dart';
import 'logged_in_view.dart';
import 'logged_out_view.dart';


void main() async {
 WidgetsFlutterBinding.ensureInitialized();
 await Firebase.initializeApp(
   options: DefaultFirebaseOptions.currentPlatform,
 );

 if (kDebugMode) {
   try {
     FirebaseFirestore.instance.useFirestoreEmulator('localhost', 8080);
     await FirebaseAuth.instance.useAuthEmulator('localhost', 9099);
   } catch (e) {
     // ignore: avoid_print
     print(e);
   }
 }

 runApp(MyApp());
}

कोड की शुरुआती कुछ लाइनें, Firebase को शुरू करती हैं. अगर आपको किसी Flutter ऐप्लिकेशन में Firebase का इस्तेमाल करना है, तो आपको सबसे पहले WidgetsFlutterBinding.ensureInitialized और Firebase.initializeApp को कॉल करना होगा.

इसके बाद, if (kDebugMode) से शुरू होने वाला कोड, आपके ऐप्लिकेशन को प्रोडक्शन Firebase प्रोजेक्ट के बजाय एम्युलेटर को टारगेट करने के लिए कहता है. kDebugMode से यह पक्का किया जाता है कि इम्यूलेटर को सिर्फ़ तब टारगेट किया जाएगा, जब आप डेवलपमेंट एनवायरमेंट में हों. kDebugMode एक कॉन्स्टेंट वैल्यू है. इसलिए, Dart कंपाइलर को पता है कि रिलीज़ मोड में उस कोड ब्लॉक को पूरी तरह से हटाना है.

एम्युलेटर शुरू करना

Flutter ऐप्लिकेशन शुरू करने से पहले, आपको इम्यूलेटर शुरू करने चाहिए. सबसे पहले, टर्मिनल में यह कमांड चलाकर इम्यूलेटर शुरू करें:

firebase emulators:start

इस कमांड से एम्युलेटर बूट हो जाते हैं. साथ ही, लोकल होस्ट पोर्ट दिखते हैं, जिनसे हम इनके साथ इंटरैक्ट कर सकते हैं. उस निर्देश को चलाने पर, आपको इससे मिलता-जुलता आउटपुट दिखेगा:

bb7181eb70829606.png

इस आउटपुट से पता चलता है कि कौनसे एम्युलेटर चल रहे हैं और एम्युलेटर देखने के लिए कहां जाना है. सबसे पहले, localhost:4000 पर जाकर, एम्युलेटर का यूज़र इंटरफ़ेस देखें.

11563f4c7216de81.png

यह लोकल एम्युलेटर के यूज़र इंटरफ़ेस (यूआई) का होम पेज है. इसमें उपलब्ध सभी एम्युलेटर की सूची दी गई है. साथ ही, हर एम्युलेटर के लिए यह बताया गया है कि वह चालू है या बंद.

5. Firebase Auth Emulator

आपको सबसे पहले, पुष्टि करने वाले एम्युलेटर का इस्तेमाल करना होगा. यूज़र इंटरफ़ेस (यूआई) में मौजूद Authentication कार्ड पर, "Go to emulator" पर क्लिक करके, Auth emulator का इस्तेमाल शुरू करें. इसके बाद, आपको यह पेज दिखेगा:

3c1bfded40733189.png

यह पेज, Auth वेब कंसोल पेज से मिलता-जुलता है. इसमें एक टेबल होती है, जिसमें ऑनलाइन कंसोल की तरह उपयोगकर्ताओं की सूची होती है. साथ ही, इसमें उपयोगकर्ताओं को मैन्युअल तरीके से जोड़ने की सुविधा भी होती है. यहां एक बड़ा अंतर यह है कि एम्युलेटर पर, पुष्टि करने के लिए सिर्फ़ ईमेल और पासवर्ड का इस्तेमाल किया जा सकता है. यह लोकल डेवलपमेंट के लिए काफ़ी है.

इसके बाद, आपको Firebase Auth एम्युलेटर में किसी उपयोगकर्ता को जोड़ने की प्रोसेस के बारे में बताया जाएगा. साथ ही, Flutter यूज़र इंटरफ़ेस (यूआई) के ज़रिए उस उपयोगकर्ता को लॉग इन करने के बारे में बताया जाएगा.

उपयोगकर्ता को जोड़ना

"उपयोगकर्ता जोड़ें" बटन पर क्लिक करें और इस जानकारी के साथ फ़ॉर्म भरें:

  • डिसप्ले नेम: डैश
  • ईमेल: dash@email.com
  • पासवर्ड: dashword

फ़ॉर्म सबमिट करें. अब आपको टेबल में एक उपयोगकर्ता दिखेगा. अब उस उपयोगकर्ता के खाते से लॉग इन करने के लिए, कोड को अपडेट किया जा सकता है.

logged_out_view.dart

LoggedOutView विजेट में सिर्फ़ उस कोड को अपडेट करना होता है जो कॉलबैक में होता है. यह कॉलबैक तब ट्रिगर होता है, जब कोई उपयोगकर्ता लॉगिन बटन दबाता है. कोड को इस तरह अपडेट करें:

class LoggedOutView extends StatelessWidget {
 final AppState state;
 const LoggedOutView({super.key, required this.state});
 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       title: const Text('Firebase Emulator Suite Codelab'),
     ),
     body: Center(
       child: Column(
         mainAxisAlignment: MainAxisAlignment.center,
         children: [
          Text(
           'Please log in',
            style: Theme.of(context).textTheme.displaySmall,
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: ElevatedButton(
             onPressed: () async {
              await state.logIn('dash@email.com', 'dashword').then((_) {
                if (state.user != null) {
                 context.go('/');
                }
              });
              },
              child: const Text('Log In'),
          ),
        ),
      ],
    ),
   ),
  );
 }
}

अपडेट किया गया कोड, TODO स्ट्रिंग को उस ईमेल और पासवर्ड से बदल देता है जिसे आपने पुष्टि करने वाले एम्युलेटर में बनाया था. इसके बाद, अगली लाइन में if(true) लाइन को ऐसे कोड से बदल दिया गया है जो यह जांच करता है कि state.user शून्य है या नहीं. AppClass में मौजूद कोड से इस बारे में ज़्यादा जानकारी मिलती है.

app_state.dart

AppState में मौजूद कोड के दो हिस्सों को अपडेट करना होगा. सबसे पहले, क्लास मेंबर AppState.user को firebase_auth पैकेज से User टाइप दें. इसके बजाय, Object टाइप दें.

दूसरा, AppState.login तरीके का इस्तेमाल करके वैल्यू भरें. इसके लिए, यहां दिया गया तरीका अपनाएं:

import 'dart:async';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';

import 'entry.dart';

class AppState {
 AppState() {
   _entriesStreamController = StreamController.broadcast(onListen: () {
     _entriesStreamController.add([
       Entry(
         date: '10/09/2022',
         text: lorem,
         title: '[Example] My Journal Entry',
       )
     ]);
   });
 }

 User? user; // <-- changed variable type
 Stream<List<Entry>> get entries => _entriesStreamController.stream;
 late final StreamController<List<Entry>> _entriesStreamController;

 Future<void> logIn(String email, String password) async {
   final credential = await FirebaseAuth.instance
       .signInWithEmailAndPassword(email: email, password: password);
   if (credential.user != null) {
     user = credential.user!;
     _listenForEntries();
   } else {
     print('no user!');
   }
 } 
 // ...
}

उपयोगकर्ता के लिए टाइप की परिभाषा अब User? है. वह User क्लास, Firebase Auth से मिलती है. साथ ही, यह ज़रूरी जानकारी देती है. जैसे, User.displayName. इसके बारे में हम थोड़ी देर में बात करेंगे.

यह Firebase Auth में ईमेल और पासवर्ड की मदद से किसी उपयोगकर्ता को लॉग इन करने के लिए ज़रूरी बुनियादी कोड है. यह FirebaseAuth को साइन इन करने के लिए कॉल करता है. इससे Future<UserCredential> ऑब्जेक्ट मिलता है. जब फ़्यूचर पूरा हो जाता है, तब यह कोड यह जांच करता है कि UserCredential से कोई User अटैच है या नहीं. अगर क्रेडेंशियल ऑब्जेक्ट पर कोई उपयोगकर्ता मौजूद है, तो इसका मतलब है कि उपयोगकर्ता ने लॉग इन कर लिया है. इसके बाद, AppState.user प्रॉपर्टी सेट की जा सकती है. अगर ऐसा नहीं होता है, तो इसका मतलब है कि कोई गड़बड़ी हुई है और उसे प्रिंट किया गया है.

ध्यान दें कि इस तरीके में, सिर्फ़ एक लाइन का कोड इस ऐप्लिकेशन के लिए खास है. यह सामान्य FirebaseAuth कोड नहीं है. यह _listenForEntries तरीके को कॉल करता है, जिसके बारे में अगले चरण में बताया जाएगा.

TODO: Action Icon – Reload your app, and then press the Login button when it renders. इससे ऐप्लिकेशन, ऐसे पेज पर पहुंच जाता है जिस पर सबसे ऊपर "आपका फिर से स्वागत है, व्यक्ति!" लिखा होता है. पुष्टि करने की सुविधा काम कर रही है, क्योंकि इसकी वजह से ही आपको इस पेज पर जाने की अनुमति मिली है. हालांकि, उपयोगकर्ता का असली नाम दिखाने के लिए, logged_in_view.dart में एक छोटा सा अपडेट करना होगा.

logged_in_view.dart

LoggedInView.build तरीके में पहली लाइन बदलें:

class LoggedInView extends StatelessWidget {
 final AppState state;
 LoggedInView({super.key, required this.state});

 final PageController _controller = PageController(initialPage: 1);

 @override
 Widget build(BuildContext context) {
   final name = state.user!.displayName ?? 'No Name';

   return Scaffold(
 // ...

अब यह लाइन, AppState ऑब्जेक्ट पर मौजूद User प्रॉपर्टी से displayName को फ़ेच करती है. जब आपने पहले उपयोगकर्ता को तय किया था, तब यह displayName एम्युलेटर में सेट किया गया था. अब आपको लॉग इन करने पर, TODO के बजाय "वेलकम बैक, डैश!" दिखना चाहिए.

6. Firestore Emulator में डेटा पढ़ना और लिखना

सबसे पहले, Firestore Emulator के बारे में जानें. एम्युलेटर के यूज़र इंटरफ़ेस (यूआई) के होम पेज (localhost:4000) पर, Firestore कार्ड में "एम्युलेटर पर जाएं" पर क्लिक करें. यह ऐसा दिखना चाहिए:

एम्युलेटर:

791fce7dc137910a.png

Firebase कंसोल:

e0dde9aea34af050.png

अगर आपने Firestore का इस्तेमाल किया है, तो आपको पता चलेगा कि यह पेज, Firebase कंसोल के Firestore पेज जैसा दिखता है. हालांकि, इनमें कुछ खास अंतर हैं.

  1. एक बटन पर टैप करके, पूरा डेटा मिटाया जा सकता है. प्रोडक्शन डेटा के साथ ऐसा करना खतरनाक हो सकता है. हालांकि, इससे तेज़ी से बदलाव करने में मदद मिलती है! अगर किसी नए प्रोजेक्ट पर काम किया जा रहा है और आपका डेटा मॉडल बदल जाता है, तो उसे आसानी से मिटाया जा सकता है.
  2. इसमें "अनुरोध" टैब मौजूद है. इस टैब की मदद से, इस एम्युलेटर को भेजे गए अनुरोधों को देखा जा सकता है. हम इस टैब के बारे में थोड़ी देर में ज़्यादा जानकारी देंगे.
  3. नियम, इंडेक्स या इस्तेमाल के लिए कोई टैब नहीं है. सुरक्षा के नियम लिखने में मदद करने वाला एक टूल उपलब्ध है. इसके बारे में अगले सेक्शन में बताया गया है. हालांकि, लोकल एम्युलेटर के लिए सुरक्षा के नियम सेट नहीं किए जा सकते.

इस सूची को छोटा करने के लिए, Firestore का यह वर्शन डेवलपमेंट के दौरान काम आने वाले ज़्यादा टूल उपलब्ध कराता है. साथ ही, उन टूल को हटा देता है जिनकी प्रोडक्शन में ज़रूरत होती है.

Firestore में डेटा सेव करने की अनुमति दें

एम्युलेटर में ‘अनुरोध' टैब के बारे में बताने से पहले, अनुरोध करें. इसके लिए, कोड अपडेट करने होंगे. सबसे पहले, ऐप्लिकेशन में फ़ॉर्म को वायर अप करें, ताकि Firestore में नई जर्नल Entry लिखी जा सके.

Entry सबमिट करने का तरीका यह है:

  1. उपयोगकर्ता ने फ़ॉर्म भर दिया है और Submit बटन दबा दिया है
  2. यूज़र इंटरफ़ेस (यूआई) AppState.writeEntryToFirebase को कॉल करता है
  3. AppState.writeEntryToFirebase Firebase में एक एंट्री जोड़ता है

पहले या दूसरे चरण में शामिल किसी भी कोड को बदलने की ज़रूरत नहीं है. तीसरे चरण के लिए, सिर्फ़ वह कोड जोड़ा जाएगा जिसे AppState क्लास में जोड़ा जाना है. AppState.writeEntryToFirebase में यह बदलाव करें.

app_state.dart

import 'dart:async';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';

import 'entry.dart';

class AppState {
 AppState() {
   _entriesStreamController = StreamController.broadcast(onListen: () {
     _entriesStreamController.add([
       Entry(
         date: '10/09/2022',
         text: lorem,
         title: '[Example] My Journal Entry',
       )
     ]);
   });
 }

 User? user;
 Stream<List<Entry>> get entries => _entriesStreamController.stream;
 late final StreamController<List<Entry>> _entriesStreamController;

 Future<void> logIn(String email, String password) async {
   final credential = await FirebaseAuth.instance
       .signInWithEmailAndPassword(email: email, password: password);
   if (credential.user != null) {
     user = credential.user!;
     _listenForEntries();
   } else {
     print('no user!');
   }
 }

 void writeEntryToFirebase(Entry entry) {
   FirebaseFirestore.instance.collection('Entries').add(<String, String>{
     'title': entry.title,
     'date': entry.date.toString(),
     'text': entry.text,
   });
 }
 // ...
}

writeEntryToFirebase तरीके में मौजूद कोड, Firestore में "Entries" नाम के कलेक्शन का रेफ़रंस लेता है. इसके बाद, एक नई एंट्री जोड़ी जाती है, जो Map<String, String> टाइप की होनी चाहिए.

इस मामले में, Firestore में "Entries" कलेक्शन मौजूद नहीं था. इसलिए, Firestore ने एक कलेक्शन बनाया.

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

फ़ॉर्म में 'सबमिट करें' पर क्लिक करें. ऐप्लिकेशन में कुछ नहीं होगा. हालांकि, आपको एम्युलेटर यूज़र इंटरफ़ेस (यूआई) में अपनी नई एंट्री दिखेगी.

Firestore Emulator में अनुरोध टैब

यूज़र इंटरफ़ेस (यूआई) में, Firestore Emulator पर जाएं और "डेटा" टैब देखें. आपको दिखेगा कि आपके डेटाबेस के रूट में अब "Entries" नाम का एक कलेक्शन है. आपके पास ऐसा दस्तावेज़ होना चाहिए जिसमें वही जानकारी हो जो आपने फ़ॉर्म में डाली है.

a978fb34fb8a83da.png

इससे पुष्टि होती है कि AppState.writeEntryToFirestore काम कर गया है. अब अनुरोध टैब में जाकर, अनुरोध के बारे में ज़्यादा जानें. अब उस टैब पर क्लिक करें.

Firestore एम्युलेटर के अनुरोध

यहां आपको एक सूची दिखेगी, जो कुछ इस तरह दिखेगी:

f0b37f0341639035.png

इनमें से किसी भी लिस्ट आइटम पर क्लिक करके, काम की कई तरह की जानकारी देखी जा सकती है. नई जर्नल एंट्री बनाने के लिए, अपने अनुरोध से मेल खाने वाले CREATE सूची आइटम पर क्लिक करें. आपको एक नई टेबल दिखेगी, जो इस तरह दिखेगी:

385d62152e99aad4.png

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

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

Firestore से डेटा पढ़ना

Firestore, डेटा सिंक करने की सुविधा का इस्तेमाल करता है. इससे कनेक्ट किए गए डिवाइसों पर अपडेट किया गया डेटा भेजा जाता है. Flutter कोड में, Firestore कलेक्शन और दस्तावेज़ों को सुना (या सदस्यता ली) जा सकता है. साथ ही, डेटा में बदलाव होने पर आपके कोड को सूचना दी जाएगी. इस ऐप्लिकेशन में, Firestore के अपडेट सुनने के लिए AppState._listenForEntries नाम के तरीके का इस्तेमाल किया जाता है.

यह कोड, StreamController और Stream के साथ काम करता है. इन्हें क्रमशः AppState._entriesStreamController और AppState.entries कहा जाता है. वह कोड पहले से लिखा गया है. साथ ही, यूज़र इंटरफ़ेस (यूआई) में Firestore से डेटा दिखाने के लिए ज़रूरी कोड भी लिखा गया है.

_listenForEntries तरीके को नीचे दिए गए कोड से मैच करने के लिए अपडेट करें:

app_state.dart

import 'dart:async';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';

import 'entry.dart';

class AppState {
 AppState() {
   _entriesStreamController = StreamController.broadcast(onListen: () {
     _entriesStreamController.add([
       Entry(
         date: '10/09/2022',
         text: lorem,
         title: '[Example] My Journal Entry',
       )
     ]);
   });
 }

 User? user;
 Stream<List<Entry>> get entries => _entriesStreamController.stream;
 late final StreamController<List<Entry>> _entriesStreamController;

 Future<void> logIn(String email, String password) async {
   final credential = await FirebaseAuth.instance
       .signInWithEmailAndPassword(email: email, password: password);
   if (credential.user != null) {
     user = credential.user!;
     _listenForEntries();
   } else {
     print('no user!');
   }
 }

 void writeEntryToFirebase(Entry entry) {
   FirebaseFirestore.instance.collection('Entries').add(<String, String>{
     'title': entry.title,
     'date': entry.date.toString(),
     'text': entry.text,
   });
 }

 void _listenForEntries() {
   FirebaseFirestore.instance
       .collection('Entries')
       .snapshots()
       .listen((event) {
     final entries = event.docs.map((doc) {
       final data = doc.data();
       return Entry(
         date: data['date'] as String,
         text: data['text'] as String,
         title: data['title'] as String,
       );
     }).toList();

     _entriesStreamController.add(entries);
   });
 }
 // ...
}

यह कोड, Firestore में मौजूद "Entries" कलेक्शन को सुनता है. जब Firestore इस क्लाइंट को नए डेटा के बारे में सूचना देता है, तो वह उस डेटा को पास करता है. साथ ही, _listenForEntries में मौजूद कोड, उसके सभी चाइल्ड दस्तावेज़ों को एक ऐसे ऑब्जेक्ट में बदल देता है जिसका इस्तेमाल हमारा ऐप्लिकेशन कर सकता है (Entry). इसके बाद, वह उन एंट्री को StreamController में जोड़ देता है. इसे _entriesStreamController कहा जाता है (यूज़र इंटरफ़ेस (यूआई) इसे सुन रहा है). सिर्फ़ इस कोड को अपडेट करना ज़रूरी है.

आखिर में, याद रखें कि AppState.logIn तरीका, _listenForEntries को कॉल करता है. इससे उपयोगकर्ता के लॉग इन करने के बाद, सुनने की प्रोसेस शुरू हो जाती है.

// ...
Future<void> logIn(String email, String password) async {
 final credential = await FirebaseAuth.instance
     .signInWithEmailAndPassword(email: email, password: password);
 if (credential.user != null) {
   user = credential.user!;
   _listenForEntries();
 } else {
   print('no user!');
 }
}
// ...

अब ऐप्लिकेशन चलाएं. यह ऐसा दिखना चाहिए:

b8a31c7a8900331.gif

7. इम्यूलेटर में डेटा एक्सपोर्ट और इंपोर्ट करना

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

इम्युलेटर का डेटा एक्सपोर्ट करना

सबसे पहले, अपने पास मौजूद एम्युलेटर डेटा को एक्सपोर्ट करें. इम्यूलेटर के चालू रहने के दौरान, एक नई टर्मिनल विंडो खोलें और यह निर्देश डालें:

firebase emulators:export ./emulators_data

.emulators_data एक आर्ग्युमेंट है. इससे Firebase को पता चलता है कि डेटा को कहां एक्सपोर्ट करना है. अगर डायरेक्ट्री मौजूद नहीं है, तो उसे बनाया जाता है. उस डायरेक्ट्री के लिए, अपनी पसंद का कोई भी नाम इस्तेमाल किया जा सकता है.

इस कमांड को चलाने पर, आपको उस टर्मिनल में यह आउटपुट दिखेगा जहां आपने कमांड चलाई थी:

i  Found running emulator hub for project flutter-firebase-codelab-d6b79 at http://localhost:4400
i  Creating export directory /Users/ewindmill/Repos/codelabs/firebase-emulator-suite/complete/emulators_data
i  Exporting data to: /Users/ewindmill/Repos/codelabs/firebase-emulator-suite/complete/emulators_data
✔  Export complete

अगर आपने उस टर्मिनल विंडो पर स्विच किया है जहां इम्यूलेटर चल रहे हैं, तो आपको यह आउटपुट दिखेगा:

i  emulators: Received export request. Exporting data to /Users/ewindmill/Repos/codelabs/firebase-emulator-suite/complete/emulators_data.
✔  emulators: Export complete.

आखिर में, अगर आपको अपनी प्रोजेक्ट डायरेक्ट्री में ./emulators_data नाम की डायरेक्ट्री दिखती है, तो इसका मतलब है कि आपने जो डेटा सेव किया है वह अन्य मेटाडेटा फ़ाइलों के साथ-साथ JSON फ़ाइलों में सेव हो गया है.

इमुलेटर का डेटा इंपोर्ट करना

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

अगर इम्यूलेटर चल रहे हैं, तो उन्हें रोकने के लिए अपने टर्मिनल में CTRL+C दबाएं.

इसके बाद, emulators:start कमांड चलाएं. यह कमांड आपको पहले ही दिख चुकी है. हालांकि, इसमें एक फ़्लैग होता है, जो यह बताता है कि कौनसा डेटा इंपोर्ट करना है:

firebase emulators:start --import ./emulators_data

एम्युलेटर चालू होने पर, localhost:4000 पर जाकर एम्युलेटर के यूज़र इंटरफ़ेस (यूआई) पर जाएं. आपको वही डेटा दिखेगा जिस पर पहले काम किया जा रहा था.

एम्युलेटर बंद करने पर, डेटा अपने-आप एक्सपोर्ट हो जाए

हर डेवलपमेंट सेशन के आखिर में डेटा एक्सपोर्ट करने के बजाय, एम्युलेटर बंद करने पर डेटा अपने-आप एक्सपोर्ट हो सकता है.

इम्यूलेटर शुरू करते समय, दो अतिरिक्त फ़्लैग के साथ emulators:start कमांड चलाएं.

firebase emulators:start --import ./emulators_data --export-on-exit

वाह! अब आपका डेटा सेव हो जाएगा. साथ ही, इस प्रोजेक्ट के लिए इम्यूलेटर का इस्तेमाल करने पर, यह डेटा फिर से लोड हो जाएगा. –export-on-exit flag के लिए, किसी दूसरी डायरेक्ट्री को भी आर्ग्युमेंट के तौर पर तय किया जा सकता है. हालांकि, यह डिफ़ॉल्ट रूप से उस डायरेक्ट्री पर सेट होगा जिसे –import को पास किया गया है.

इन विकल्पों को मिलाकर भी इस्तेमाल किया जा सकता है. यह दस्तावेज़ों से लिया गया नोट है: इस फ़्लैग का इस्तेमाल करके, एक्सपोर्ट डायरेक्ट्री तय की जा सकती है: firebase emulators:start --export-on-exit=./saved-data. अगर --import का इस्तेमाल किया जाता है, तो एक्सपोर्ट पाथ डिफ़ॉल्ट रूप से वही होता है. उदाहरण के लिए: firebase emulators:start --import=./data-path --export-on-exit. आखिर में, अगर चाहें, तो --import और --export-on-exit फ़्लैग को अलग-अलग डायरेक्ट्री पाथ पास करें.

8. बधाई हो!

आपने 'Firebase Emulator और Flutter का इस्तेमाल शुरू करना' कोर्स पूरा कर लिया हो. आपको इस कोडलैब का पूरा कोड, GitHub पर "complete" डायरेक्ट्री में मिल जाएगा: Flutter Codelabs

हमने क्या-क्या कवर किया है

  • Firebase का इस्तेमाल करने के लिए, Flutter ऐप्लिकेशन सेट अप करना
  • Firebase प्रोजेक्ट सेट अप करना
  • FlutterFire CLI
  • Firebase CLI
  • Firebase Authentication Emulator
  • Firebase Firestore एम्युलेटर
  • इमुलेटर का डेटा इंपोर्ट और एक्सपोर्ट करना

अगले चरण

  • Flutter में Firestore और Authentication का इस्तेमाल करने के बारे में ज़्यादा जानें: Firebase for Flutter Codelab के बारे में जानें
  • Firebase के ऐसे अन्य टूल एक्सप्लोर करें जो एम्युलेटर उपलब्ध कराते हैं:
  • Cloud Storage
  • Cloud Functions
  • Realtime Database
  • अपने ऐप्लिकेशन में Google Authentication की सुविधा को तुरंत जोड़ने के लिए, FlutterFire UI एक्सप्लोर करें.

ज़्यादा जानें

स्पार्की को आप पर गर्व है!

2a0ad195769368b1.gif