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

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

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

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

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

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

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

यह कोडलैब आपको एक आसान Journaling ऐप्लिकेशन बनाने में मदद करता है. ऐप्लिकेशन में एक लॉगिन स्क्रीन होगी और एक स्क्रीन होगी जो आपको पिछली जर्नल एंट्री पढ़ने और नई बनाने की सुविधा देती है.

cd5c4753bbee8af.png 8cb4d21f656540bf.png

आपको यह जानकारी मिलेगी

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

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

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

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

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

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

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

  1. Firebase कंसोल में साइन इन करें.
  2. Firebase कंसोल में, प्रोजेक्ट जोड़ें (या प्रोजेक्ट बनाएं) पर क्लिक करें और अपने Firebase प्रोजेक्ट के लिए एक नाम डालें (उदाहरण के लिए, "Firebase-Flutter-Codelab").

फ़े6aeab3b91965ed.png

  1. प्रोजेक्ट बनाने के विकल्पों पर क्लिक करें. अनुरोध किए जाने पर, Firebase की शर्तें स्वीकार करें. Google Analytics को सेट अप न करें, क्योंकि इस ऐप्लिकेशन के लिए Analytics का इस्तेमाल नहीं किया जाएगा.

d1fcec48bf251eaa.png

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

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

  • Firebase से पुष्टि करने की सुविधा की मदद से, उपयोगकर्ता आपके ऐप्लिकेशन में साइन इन कर सकते हैं.
  • स्ट्रक्चर्ड डेटा को क्लाउड पर सेव करने और डेटा में बदलाव होने पर तुरंत सूचना पाने के लिए, 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 सीएलआई इंस्टॉल करना होगा.

स्टार्टर कोड पाएं

कमांड लाइन से, 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 सीएलआई इंस्टॉल करें

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

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

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

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

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

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

FlutterFire सीएलआई को Firebase सीएलआई पर बनाया गया है. इससे आपके Flutter ऐप्लिकेशन के साथ Firebase प्रोजेक्ट को इंटिग्रेट करना आसान हो जाता है.

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

dart pub global activate flutterfire_cli

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

flutterfire --help

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

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

सबसे पहले, नीचे दिया गया तरीका अपनाकर Firebase का सेट अप पूरा करें:

firebase init

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

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

f11dcab439e6ac1e.png

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

3bdc0c6934991c25.png

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

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

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

8544e41037637b07.png

FlutterFire को कॉन्फ़िगर करें

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

flutterfire configure

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

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

619b7aca6dc15472.png 301c9534f594f472.png

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

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 अनुरोधों को स्थानीय पोर्ट पर ले जा सकें.

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

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 शुरू करती हैं. अगर Firebase के साथ Flutter ऐप्लिकेशन में काम किया जा रहा है, तो करीब-करीब सभी तरीकों से शुरुआत करने के लिए WidgetsFlutterBinding.ensureInitialized और Firebase.initializeApp को कॉल करें.

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

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

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

firebase emulators:start

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

bb7181eb70829606.png

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

11563f4c7216de81.png

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

5. Firebase पुष्टि करने वाला एम्युलेटर

सबसे पहले इस्तेमाल किया जाने वाला एम्युलेटर, पुष्टि करने वाला एम्युलेटर है. "सिम्युलेटर पर जाएं" पर क्लिक करके, पुष्टि करने के टूल से शुरुआत करें पर साइन इन करें और आपको ऐसा पेज दिखेगा:

3c1bfded40733189.png

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

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

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

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

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

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

Log_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 को Object टाइप की जगह firebase_auth पैकेज से User टाइप दें.

इसके बाद, नीचे दिए गए तरीके से 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 पुष्टि से मिलती है और इसमें User.displayName जैसी ज़रूरी जानकारी मिलती है, जिसके बारे में थोड़ी देर में बताया गया है.

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

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

TODO: कार्रवाई आइकन – अपना ऐप्लिकेशन फिर से लोड करें, और फिर जब वह रेंडर हो जाए तो लॉगिन बटन दबाएं. इससे ऐप्स ऐसे पेज पर नेविगेट हो जाता है, जो कहता है "आपका फिर से स्वागत है, व्यक्ति!" क्लिक करें. पुष्टि करने की प्रोसेस काम करनी चाहिए, क्योंकि इससे आपको इस पेज पर जाने की अनुमति है. हालांकि, उपयोगकर्ता का असल नाम दिखाने के लिए, logged_in_view.dart में मामूली अपडेट करना होगा.

Log_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 एम्युलेटर में डेटा पढ़ें और लिखें

सबसे पहले, Firestore एम्युलेटर देखें. एम्युलेटर यूज़र इंटरफ़ेस (यूआई) के होम पेज (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 तरीके में मौजूद कोड "Entries" कलेक्शन का रेफ़रंस लेता है Firestore में. इसके बाद, एक नई एंट्री जुड़ जाती है, जो Map<String, String> टाइप की होनी चाहिए.

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

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

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

Firestore एम्युलेटर में अनुरोध टैब

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

a978fb34fb8a83da.png

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

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

यहां आपको इससे मिलती-जुलती एक सूची दिखेगी:

f0b37f0341639035.png

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

385d62152e99aad4.png

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

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

Firestore से पढ़ना

Firestore, अपडेट किए गए डेटा को कनेक्ट किए गए डिवाइसों में पुश करने के लिए, डेटा सिंक करने की सुविधा का इस्तेमाल करता है. Flutter कोड में Firebase के कलेक्शन और दस्तावेज़ सुने जा सकते हैं या उनकी सदस्यता ली जा सकती है. डेटा में कोई भी बदलाव होने पर आपके कोड को सूचना दी जाएगी. इस ऐप्लिकेशन में, 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 इस क्लाइंट को नया डेटा उपलब्ध होने की सूचना देता है, तब वह उस डेटा को पास करता है. साथ ही, _listenForEntries में मौजूद कोड अपने सभी चाइल्ड दस्तावेज़ों को किसी ऐसे ऑब्जेक्ट में बदल देता है जिसे हमारा ऐप्लिकेशन इस्तेमाल कर सकता है (Entry). इसके बाद, यह उन एंट्री को _entriesStreamController नाम के StreamController में जोड़ देता है (जिसे यूज़र इंटरफ़ेस (यूआई) सुन रहा है). सिर्फ़ इस कोड को अपडेट करने की ज़रूरत है.

आखिर में, याद रखें कि 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 एम्युलेटर, डेटा को इंपोर्ट और एक्सपोर्ट करने की सुविधा देते हैं. इंपोर्ट और एक्सपोर्ट का इस्तेमाल करने से, आपको डेवलपमेंट से कुछ समय के लिए ब्रेक लेने के बाद फिर से उसी डेटा के साथ डेवलपमेंट को जारी रखने में मदद मिलती है. आप डेटा फ़ाइलों को 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 एम्युलेटर और Flutter के साथ इस्तेमाल करने और उन्हें चलाने का काम पूरा कर लिया है. इस कोडलैब के लिए पूरा कोड देखने के लिए, "पूरा हुआ" कॉलम देखें GitHub पर डायरेक्ट्री: Flutter कोडलैब

हमने इन विषयों के बारे में बताया

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

अगले चरण

और जानें

Sparky को आप पर गर्व है!

2a0ad195769368b1.gif