Firebase for Flutter'ı tanıyın

1. Başlamadan önce

Bu codelab olarak, ilgili bazı temel unsurları öğreneceksiniz Firebase Android ve iOS için Flutter mobil uygulamalar oluşturma.

Önkoşullar

Bu codelab Eğer Flutter aşina olduklarını ve yüklediğiniz Flutter SDK ve bir editör .

ne yaratacaksın

Bu kod laboratuvarında, Flutter kullanarak Android, iOS, Web ve macOS üzerinde bir etkinlik LCV ve ziyaretçi defteri sohbet uygulaması oluşturacaksınız. Firebase Authentication ile kullanıcıların kimliğini doğrulayacak ve Cloud Firestore'u kullanarak verileri senkronize edeceksiniz.

Neye ihtiyacın olacak

Bu codelab'i aşağıdaki cihazlardan herhangi birini kullanarak çalıştırabilirsiniz:

  • Bilgisayarınıza bağlı ve geliştirici moduna ayarlanmış fiziksel bir cihaz (Android veya iOS).
  • iOS simülatörü. (Gerektirir Xcode araçlarını yükleyerek .)
  • Android öykünücüsü. (İçinde kurulum gerektirir Android Studio .)

Yukarıdakilere ek olarak, şunlara da ihtiyacınız olacak:

  • Chrome gibi seçtiğiniz bir tarayıcı.
  • Bir IDE veya gibi seçtiğiniz metin editörü, Android Studio veya VS Kanunu Dart ve Flutter eklentileri ile yapılandırılmış.
  • Son stable sürümü Flutter (veya beta Eğer kenarında yaşayan keyfini ise).
  • Firebase projenizi oluşturmak ve yönetmek için gmail hesabı gibi bir Google hesabı.
  • firebase komut satırı aracı , gmail hesaba giriş.
  • Codelab'ın örnek kodu. Kodun nasıl alınacağını öğrenmek için sonraki adıma bakın.

2. Örnek kodu alın

Projemizin ilk sürümünü GitHub'dan indirerek başlayalım.

Klon GitHub depo komut satırından:

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

Alternatif olarak, varsa Github en cli aracı yüklü:

gh repo clone flutter/codelabs flutter-codelabs

Örnek kod içine klonlanmış edilmelidir flutter-codelabs CodeLabs bir koleksiyon kodunu içeren dizine. Bu codelab için kod içindedir flutter-codelabs/firebase-get-to-know-flutter .

Altında dizin yapısı flutter-codelabs/firebase-get-to-know-flutter her adlandırılmış adımın sonunda olması gereken yerde bir anlık dizisidir. Bu 2. Adımdır, bu nedenle eşleşen dosyaları bulmak şu kadar kolaydır:

cd flutter-codelabs/firebase-get-to-know-flutter/step_02

İleri atlamak veya bir adımdan sonra bir şeyin nasıl görünmesi gerektiğini görmek istiyorsanız, ilgilendiğiniz adımın adını taşıyan dizine bakın.

Başlangıç ​​uygulamasını içe aktarın

Aç içe veya flutter-codelabs/firebase-get-to-know-flutter/step_02 tercih IDE içine dizinde. Bu dizin, henüz işlevsel olmayan bir Flutter buluşma uygulamasından oluşan kod laboratuvarı için başlangıç ​​kodunu içerir.

Üzerinde çalışılacak dosyaları bulun

Bu uygulamadaki kod, birden çok dizine yayılmıştır. Bu işlevsellik ayrımı, kodu işlevselliğe göre gruplayarak üzerinde çalışmayı kolaylaştırmak için tasarlanmıştır.

Projede aşağıdaki dosyaları bulun:

  • lib/main.dart : Bu dosya ana giriş noktası ve uygulama widget'ı bulunur.
  • lib/src/widgets.dart : Bu dosya yardım standardize etmek widget bir avuç uygulamasının stil içerir. Bunlar, başlangıç ​​uygulamasının ekranını oluşturmak için kullanılır.
  • lib/src/authentication.dart : Bu dosya kısmi uygulanmasını içeren FirebaseUI Auth Firebase eposta tabanlı kimlik doğrulaması için oturum açma kullanıcı deneyimi yaratmak için widget seti ile. Yetkilendirme akışına yönelik bu widget'lar henüz başlangıç ​​uygulamasında kullanılmamaktadır, ancak bunları yakında bağlayacaksınız.

Uygulamanın geri kalanını oluşturmak için gerektiği kadar ek dosyalar ekleyeceksiniz.

Gözden lib/main.dart dosyası

Bu uygulama yararlanır google_fonts bütün Uygulamanın tamamında Roboto varsayılan yazı tipini yapmamızı sağlayacak paketin. Motive okuyucu için bir egzersiz keşfetmektir fonts.google.com ve uygulamanın farklı yerlerinde orada keşfetmek fontları kullanın.

Sen den yardımcı widget'lar kullanıyor lib/src/widgets.dart şeklinde Header , Paragraph ve IconAndDetail . Bu widget'lar tarif sayfa düzeninde yığılmayı azaltmak HomePage çoğaltılamaz kodunu ortadan kaldırarak. Bu, tutarlı bir görünüm ve his sağlamanın ek avantajına sahiptir.

Uygulamanız Android, iOS, Web ve macOS'ta şöyle görünür:

Uygulama önizlemesi

3. Bir Firebase projesi oluşturun ve kurun

Etkinlik bilgilerini görüntülemek konuklarınız için harikadır, ancak yalnızca etkinlikleri göstermek hiç kimse için pek yararlı değildir. Bu uygulamaya bazı dinamik işlevler ekleyelim. Bunun için Firebase'i uygulamanıza bağlamanız gerekir. Firebase'i kullanmaya başlamak için bir Firebase projesi oluşturmanız ve ayarlamanız gerekir.

Bir Firebase projesi oluşturun

  1. Oturum açın Firebase .
  2. Firebase konsolunda, tıklayın Project ekleyin (veya Proje oluşturma), ve Firebase proje Firebase-Flutter-Codelab isim.

4395e4e67c08043a.png

  1. Proje oluşturma seçeneklerine tıklayın. İstenirse Firebase şartlarını kabul edin. Bu uygulama için Analytics kullanmayacağınız için Google Analytics kurulumunu atlayın.

b7138cde5f2c7b61.png

Firebase projeleri hakkında daha fazla bilgi edinmek için bkz Firebase projeleri anlayın .

Oluşturduğunuz uygulama, web uygulamaları için kullanılabilen birkaç Firebase ürünü kullanıyor:

  • Doğrulama Firebase Kullanıcıların uygulamanızın oturum açmak için izin vermek.
  • Bulut Firestore bulut yapılandırılmış verileri kaydetmek ve ne zaman veri değişiklikleri anında bildirim almak için.
  • Firebase Güvenlik Kuralları veritabanını güvenli.

Bu ürünlerden bazıları özel yapılandırmaya ihtiyaç duyar veya Firebase konsolu kullanılarak etkinleştirilmesi gerekir.

E-posta Firebase Kimlik Doğrulama için oturum açma etkinleştirme

Kullanıcıların web uygulamasında oturum izin vermek için, bu codelab için yönteminde oturum açma E-posta / Şifre kullanacağız:

  1. Firebase konsolunda, sol panelde Yapı menüsünü genişletin.
  2. Kimlik ve ardından Başlayın düğmesini, ardından yöntemde Oturum açma sekmesini tıklayın (veya buraya tıklayın Sign-in yöntemi sekmesine doğrudan gitmek için).
  3. Anahtarı açık konumuna etkinleştirme ve ardından Kaydet'i tıklayın set, sağlayıcılar Oturum listede E-posta / Şifre tıklayın. 58e3e3e23c2f16a4.png

Cloud Firestore'u Etkinleştir

Web uygulaması kullanan Bulut FireStore sohbet mesajlarını kaydetmek ve yeni sohbet mesajları almak için.

Cloud Firestore'u etkinleştirin:

  1. Firebase konsolunun Yapı bölümünde, Bulut FireStore tıklayın.
  2. Veritabanı oluşturun tıklayın. 99e8429832d23fa3.png
  1. Test modu seçeneğini Başlat seçin. Güvenlik kurallarıyla ilgili sorumluluk reddini okuyun. Test modu, geliştirme sırasında veritabanına özgürce yazabilmenizi sağlar. İleri 'yi tıklayın. 6be00e26c72ea032.png
  1. Veritabanınız için konumu seçin (Yalnızca varsayılanı kullanabilirsiniz). Bu konumun daha sonra değiştirilemeyeceğini unutmayın. 278656eefcfb0216.png
  2. Etkinleştir'i tıklayın.

4. Firebase yapılandırması

Firebase'i Flutter ile kullanmak için Flutter projesini FlutterFire kitaplıklarını doğru kullanacak şekilde yapılandırmak için bir süreci izlemeniz gerekir:

  • Projenize FlutterFire bağımlılıklarını ekleyin
  • İstediğiniz platformu Firebase projesine kaydedin
  • Platforma özel yapılandırma dosyasını indirin ve koda ekleyin.

Senin Flutter uygulamasının en üst düzey dizinde, denilen alt dizinleri vardır android , ios , macos ve web . Bu dizinler, sırasıyla iOS ve Android için platforma özgü yapılandırma dosyalarını tutar.

Bağımlılıkları yapılandır

Bu uygulamada kullandığınız iki Firebase ürünü için FlutterFire kitaplıklarını eklemeniz gerekir - Firebase Auth ve Cloud Firestore. Bağımlılıkları eklemek için aşağıdaki üç komutu çalıştırın.

$ flutter pub add firebase_core 
Resolving dependencies...
+ firebase_core 1.10.5
+ firebase_core_platform_interface 4.2.2
+ firebase_core_web 1.5.2
+ flutter_web_plugins 0.0.0 from sdk flutter
+ js 0.6.3
  test_api 0.4.3 (0.4.8 available)
Changed 5 dependencies!

firebase_core tüm Firebase Flutter eklentileri için gerekli ortak koddur.

$ flutter pub add firebase_auth
Resolving dependencies...
+ firebase_auth 3.3.3
+ firebase_auth_platform_interface 6.1.8
+ firebase_auth_web 3.3.4
+ intl 0.17.0
  test_api 0.4.3 (0.4.8 available)
Changed 4 dependencies!

firebase_auth Firebase en Kimlik yeteneği entegrasyonu sağlar.

$ flutter pub add cloud_firestore
Resolving dependencies...
+ cloud_firestore 3.1.4
+ cloud_firestore_platform_interface 5.4.9
+ cloud_firestore_web 2.6.4
  test_api 0.4.3 (0.4.8 available)
Changed 3 dependencies!

cloud_firestore Bulut Firestore veri depolama erişimi sağlar.

$ flutter pub add provider
Resolving dependencies...
+ nested 1.0.0
+ provider 6.0.1
  test_api 0.4.3 (0.4.8 available)
Changed 2 dependencies!

Gerekli paketleri eklerken, Firebase'i uygun şekilde kullanmak için iOS, Android, macOS ve Web runner projelerini de yapılandırmanız gerekir. Ayrıca kullandığınız provider ekran mantıktan iş mantığı ayrılmasını sağlayacak paketi.

yükleme flutterfire

  1. FlutterFire CLI, temeldeki Firebase CLI'ye bağlıdır. Daha önce yapmadıysanız, yüklemek veya en son sürüme güncelleme Firebase CLI .
  2. : Sonra, aşağıdaki komutu çalıştırarak FlutterFire CLI yüklemek
    $ dart pub global activate flutterfire_cli
    

Yükleme tamamlandıktan sonra, flutterfire komut genel kullanıma açılır.

Uygulamalarınızı yapılandırma

CLI, belirli bir platform için tüm yapılandırmayı oluşturmak üzere Firebase projenizden ve seçilen proje uygulamalarından bilgi alır.

Uygulamanızın kökünde, configure komutunu çalıştırın:

$ flutterfire configure

Konfigürasyon komutu bir dizi işlemde size rehberlik edecektir:

  1. Bir Firebase projesi seçme (.firebaserc dosyasına göre veya Firebase Konsolundan).
  2. Hangi platformlar için (örn. Android, iOS, macOS ve web) yapılandırmak istediğinizi belirtin.
  3. Yapılandırmayı çıkarmak için seçilen platformlar için hangi Firebase uygulamalarının kullanılması gerektiğini belirleyin. Varsayılan olarak, CLI, mevcut proje yapılandırmanıza göre Firebase uygulamalarını otomatik olarak eşleştirmeye çalışır.
  4. Projenizde bir firebase_options.dart dosyası oluşturun.

macOS'u yapılandırın

MacOS'ta Flutter, tamamen korumalı uygulamalar oluşturur. Bu uygulama, Firebase sunucularıyla iletişim kurmak için ağı kullanarak entegre olduğundan, uygulamanızı ağ istemcisi ayrıcalıklarıyla yapılandırmanız gerekecektir.

macos/Runner/DebugProfile.yetkilendirmeleri

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.security.app-sandbox</key>
	<true/>
	<key>com.apple.security.cs.allow-jit</key>
	<true/>
	<key>com.apple.security.network.server</key>
	<true/>
  <!-- Add the following two lines -->
	<key>com.apple.security.network.client</key>
	<true/>
</dict>
</plist>

macos/Runner/Release.yetkilendirmeleri

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.security.app-sandbox</key>
	<true/>
  <!-- Add the following two lines -->
	<key>com.apple.security.network.client</key>
	<true/>
</dict>
</plist>

Bkz haklar ve Uygulama Sandbox daha fazla ayrıntı için.

5. Kullanıcı oturum açma (RSVP) ekleyin

Şimdi app Firebase eklediğiniz için, kullanmakta kayıtları insanlar o bir LCV düğmesi ayarlayabilirsiniz Firebase Authentication . Android yerel, iOS yerel ve Web için önceden oluşturulmuş FirebaseUI Auth paketleri vardır, ancak Flutter için bu özelliği oluşturmanız gerekir.

Adım 2'de aldığınız proje, kimlik doğrulama akışının çoğu için kullanıcı arabirimini uygulayan bir dizi pencere öğesi içeriyordu. Firebase Authentication'ı uygulamaya entegre etmek için iş mantığını uygulayacaksınız.

Sağlayıcı ile İş Mantığı

Sen kullanacağız provider Flutter widget uygulamanın ağacının boyunca merkezi bir uygulama durum nesnesi kullanılabilir hale getirmek için paketi. Üstündeki ithalatı değiştirme Başlangıç olarak lib/main.dart :

lib/main.dart

import 'package:firebase_auth/firebase_auth.dart'; // new
import 'package:firebase_core/firebase_core.dart'; // new
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';           // new

import 'firebase_options.dart';                    // new
import 'src/authentication.dart';                  // new
import 'src/widgets.dart';

import hatları Firebase Çekirdek ve Auth, içinde çekme tanıtmak provider Widget'ta ağacında uygulama durum nesnesi kullanılabilir hale getirmek için kullandığınız paketin ve gelen doğrulama widget'ları lib/src .

Bu uygulama durumu nesnesi ApplicationState , bu adım için iki ana sorumlulukları vardır, ancak daha sonra adımlarda uygulamaya fazla yetenek ekleyin gibi ek sorumluluklar kazanacaktır. İlk sorumluluk çağrısı ile Firebase kütüphane başlatmak için olduğunu Firebase.initializeApp() ve ardından yetkilendirme akışının işleme yoktur. Sonuna aşağıdaki sınıfını ekleyin lib/main.dart :

lib/main.dart

class ApplicationState extends ChangeNotifier {
  ApplicationState() {
    init();
  }

  Future<void> init() async {
    await Firebase.initializeApp(
      options: DefaultFirebaseOptions.currentPlatform,
    );

    FirebaseAuth.instance.userChanges().listen((user) {
      if (user != null) {
        _loginState = ApplicationLoginState.loggedIn;
      } else {
        _loginState = ApplicationLoginState.loggedOut;
      }
      notifyListeners();
    });
  }

  ApplicationLoginState _loginState = ApplicationLoginState.loggedOut;
  ApplicationLoginState get loginState => _loginState;

  String? _email;
  String? get email => _email;

  void startLoginFlow() {
    _loginState = ApplicationLoginState.emailAddress;
    notifyListeners();
  }

  Future<void> verifyEmail(
    String email,
    void Function(FirebaseAuthException e) errorCallback,
  ) async {
    try {
      var methods =
          await FirebaseAuth.instance.fetchSignInMethodsForEmail(email);
      if (methods.contains('password')) {
        _loginState = ApplicationLoginState.password;
      } else {
        _loginState = ApplicationLoginState.register;
      }
      _email = email;
      notifyListeners();
    } on FirebaseAuthException catch (e) {
      errorCallback(e);
    }
  }

  Future<void> signInWithEmailAndPassword(
    String email,
    String password,
    void Function(FirebaseAuthException e) errorCallback,
  ) async {
    try {
      await FirebaseAuth.instance.signInWithEmailAndPassword(
        email: email,
        password: password,
      );
    } on FirebaseAuthException catch (e) {
      errorCallback(e);
    }
  }

  void cancelRegistration() {
    _loginState = ApplicationLoginState.emailAddress;
    notifyListeners();
  }

  Future<void> registerAccount(
      String email,
      String displayName,
      String password,
      void Function(FirebaseAuthException e) errorCallback) async {
    try {
      var credential = await FirebaseAuth.instance
          .createUserWithEmailAndPassword(email: email, password: password);
      await credential.user!.updateDisplayName(displayName);
    } on FirebaseAuthException catch (e) {
      errorCallback(e);
    }
  }

  void signOut() {
    FirebaseAuth.instance.signOut();
  }
}

Bu sınıfta birkaç önemli noktayı belirtmekte fayda var. Kullanıcı kimliği doğrulanmadan başlar, uygulama, e-posta adresinin dosyada olup olmadığına bağlı olarak kullanıcının e-posta adresini isteyen bir form gösterir, uygulama ya kullanıcıdan kaydolmasını ister ya da şifresini ister ve ardından her şeyin yolunda gittiğini varsayarsa, kullanıcı kimliği doğrulanır.

Mevcut bir hesabı olan ve giriş yapmakta sorun yaşayan bir kullanıcının durumunu ele almadığından, bunun FirebaseUI Auth akışının tam bir uygulaması olmadığına dikkat edilmelidir. motive okuyucu

Kimlik Doğrulama akışını entegre etme

Şimdi uygulama devletin bir başlangıç olduğunu, uygulamayla başlatma içine uygulama durumunu tel ve içine doğrulama akışını ekleme zamanı olduğunu HomePage . Yoluyla uygulama durumunu entegre etmek ana giriş noktası güncelleyin provider paketinin:

lib/main.dart

void main() {
  // Modify from here
  runApp(
    ChangeNotifierProvider(
      create: (context) => ApplicationState(),
      builder: (context, _) => App(),
    ),
  );
  // to here.
}

Modifikasyon main fonksiyonu kullanarak uygulama durumu nesnenin örneğini sorumlu sağlayıcı paket yapar ChangeNotifierProvider aracını. Uygulama durum nesnesi uzanır çünkü bu özel sağlayıcı sınıfını kullanan ChangeNotifier ve bu olanak provider zaman bağımlı widget'lar yeniden görüntülemek bilmek paketi. Son olarak, birlikte uygulama durumuna entegre Authentication güncelleyerek HomePage sitesindeki build yöntemi:

lib/main.dart

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Firebase Meetup'),
      ),
      body: ListView(
        children: <Widget>[
          Image.asset('assets/codelab.png'),
          const SizedBox(height: 8),
          const IconAndDetail(Icons.calendar_today, 'October 30'),
          const IconAndDetail(Icons.location_city, 'San Francisco'),
          // Add from here
          Consumer<ApplicationState>(
            builder: (context, appState, _) => Authentication(
              email: appState.email,
              loginState: appState.loginState,
              startLoginFlow: appState.startLoginFlow,
              verifyEmail: appState.verifyEmail,
              signInWithEmailAndPassword: appState.signInWithEmailAndPassword,
              cancelRegistration: appState.cancelRegistration,
              registerAccount: appState.registerAccount,
              signOut: appState.signOut,
            ),
          ),
          // to here
          const Divider(
            height: 8,
            thickness: 1,
            indent: 8,
            endIndent: 8,
            color: Colors.grey,
          ),
          const Header("What we'll be doing"),
          const Paragraph(
            'Join us for a day full of Firebase Workshops and Pizza!',
          ),
        ],
      ),
    );
  }
}

Sen örneğini Authentication widget'ı ve sarın Consumer widget'ı. Tüketici bu olağan şekilde tarihinde eklendi provider paket ağacının uygulama durumu değişiklikleri kısmını yeniden inşa etmek için de kullanılabilir. Authentication doğrulama UI Öyle olacağına artık testidir widget.

Kimlik Doğrulama akışını test etme

cdf2d25e436bd48d.png

Kullanıcının e-posta formunu başlatmak için LCV düğmesine dokunabileceği kimlik doğrulama akışının başlangıcı burada.

2a2cd6d69d172369.png

E-postayı girdikten sonra, sistem kullanıcının kayıtlı olup olmadığını onaylar, bu durumda kullanıcıdan bir şifre istenir, alternatif olarak kullanıcı kayıtlı değilse, kayıt formuna geçer.

e5e65065dba36b54.png

Hata işleme akışını kontrol etmek için kısa bir parola (altı karakterden az) girmeyi denediğinizden emin olun. Kullanıcı kayıtlıysa, bunun yerine şifreyi görecektir.

fbb3ea35fb4f67a.png

Bu sayfada, bu sayfadaki hata işlemeyi kontrol etmek için yanlış şifreler girdiğinizden emin olun. Son olarak, kullanıcı oturum açtıktan sonra, kullanıcıya tekrar oturumu kapatma olanağı sunan oturum açma deneyimini göreceksiniz.

4ed811a25b0cf816.png

Ve bununla bir kimlik doğrulama akışı uyguladınız. Tebrikler!

6. Cloud Firestore'a mesaj yazın

Kullanıcıların geldiğini bilmek harika, ancak konuklara uygulamada yapacakları başka bir şey verelim. Ya bir ziyaretçi defterine mesaj bırakabilirlerse? Gelmek için neden heyecanlı olduklarını veya kiminle tanışmayı umduklarını paylaşabilirler.

Kullanıcılar uygulama yazma sohbet mesajlarını saklamak için kullanacağız Bulut FireStore .

Veri örneği

Cloud Firestore bir NoSQL veritabanıdır ve veritabanında depolanan veriler koleksiyonlara, belgelere, alanlara ve alt koleksiyonlara bölünür. Sen adında bir üst düzey koleksiyonunda bir belge olarak sohbet her mesajı depolayacak guestbook .

7c20dc8424bb1d84.png

Firestore'a mesaj ekleyin

Bu bölümde, kullanıcıların veritabanına yeni mesajlar yazması için işlevsellik ekleyeceksiniz. İlk olarak, UI öğelerini (form alanı ve gönder düğmesi) eklersiniz ve ardından bu öğeleri veritabanına bağlayan kodu eklersiniz.

İlk olarak, için ithalat eklemek cloud_firestore paketi ve dart:async .

lib/main.dart

import 'dart:async';                                    // new

import 'package:cloud_firestore/cloud_firestore.dart';  // new
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';

import 'firebase_options.dart';
import 'src/authentication.dart';
import 'src/widgets.dart';

Bir ileti alan ve bir gönderme düğmesi UI öğeleri oluşturmak üzere widget yeni Durum Bilgisi eklemek GuestBook altındaki lib/main.dart .

lib/main.dart

class GuestBook extends StatefulWidget {
  const GuestBook({required this.addMessage});
  final FutureOr<void> Function(String message) addMessage;

  @override
  _GuestBookState createState() => _GuestBookState();
}

class _GuestBookState extends State<GuestBook> {
  final _formKey = GlobalKey<FormState>(debugLabel: '_GuestBookState');
  final _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Form(
        key: _formKey,
        child: Row(
          children: [
            Expanded(
              child: TextFormField(
                controller: _controller,
                decoration: const InputDecoration(
                  hintText: 'Leave a message',
                ),
                validator: (value) {
                  if (value == null || value.isEmpty) {
                    return 'Enter your message to continue';
                  }
                  return null;
                },
              ),
            ),
            const SizedBox(width: 8),
            StyledButton(
              onPressed: () async {
                if (_formKey.currentState!.validate()) {
                  await widget.addMessage(_controller.text);
                  _controller.clear();
                }
              },
              child: Row(
                children: const [
                  Icon(Icons.send),
                  SizedBox(width: 4),
                  Text('SEND'),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Burada bir iki ilgi çekici nokta var. İlk önce, bir Form başlatıyorsunuz, böylece upi mesajın gerçekten bir içeriği olduğunu doğrulayabilir ve eğer yoksa kullanıcıya bir hata mesajı gösterebilir. Bir form doğrulamak için bir yol formunun arkasında formu durumunu erişen içerir ve bunun için bir kullanma GlobalKey . Keys hakkında daha fazla bilgi edinmek ve bunların nasıl kullanılacağı lütfen bkz "Kullanım Keys" Flutter Widget'lar 101 bölüm .

Ayrıca widget'ları yerleştirilir yolu not, bir var Row bir ile, TextFormField ve StyledButton kendisi içeren, Row . Ayrıca dikkat TextFormField bir in sarılır Expanded Widget, bu kuvvetler TextFormField satırda herhangi bir ekstra yer kaplar için. Daha iyi bu neden gerekli olduğu, içinden okuyunuz anlamak için anlama kısıtlamalar .

Artık, kullanıcının Ziyaretçi Defterine eklemek üzere bir metin girmesini sağlayan bir widget'ınız olduğuna göre, onu ekrana getirmeniz gerekir. Bunu yapmak için, düzenleme vücut HomePage altındaki aşağıdaki iki satırı eklemek için ListView 'çocukları:

const Header("What we'll be doing"),
const Paragraph(
  'Join us for a day full of Firebase Workshops and Pizza!',
),
// Add the following two lines.
const Header('Discussion'),
GuestBook(addMessage: (message) => print(message)),

Bu, Widget'ı görüntülemek için yeterli olsa da, yararlı bir şey yapmak için yeterli değildir. Bu kodu, işlevsel hale getirmek için kısa süre içinde güncelleyeceksiniz.

Uygulama önizlemesi

GÖNDER butonuna tıklayarak bir kullanıcı aşağıdaki kod parçacığını tetikleyecektir. Bu ileti giriş alanın içeriğini ekler guestbook veritabanının koleksiyonu. Özellikle, addMessageToGuestBook yöntem (otomatik olarak üretilen bir kimlik ile) yeni bir belge için mesaj içeriğini ekler guestbook toplama.

Not FirebaseAuth.instance.currentUser.uid tüm giriş yapan için kullanıcılara Firebase Kimlik verdiği otomatik oluşturulan benzersiz bir kimlik bir referanstır.

Başka bir değişiklik yapın lib/main.dart dosyası. Ekle addMessageToGuestBook yöntemi. Bir sonraki adımda kullanıcı arayüzünü ve bu yeteneği birbirine bağlayacaksınız.

lib/main.dart

class ApplicationState extends ChangeNotifier {

  // Current content of ApplicationState elided ...

  // Add from here
  Future<DocumentReference> addMessageToGuestBook(String message) {
    if (_loginState != ApplicationLoginState.loggedIn) {
      throw Exception('Must be logged in');
    }

    return FirebaseFirestore.instance
        .collection('guestbook')
        .add(<String, dynamic>{
      'text': message,
      'timestamp': DateTime.now().millisecondsSinceEpoch,
      'name': FirebaseAuth.instance.currentUser!.displayName,
      'userId': FirebaseAuth.instance.currentUser!.uid,
    });
  }
  // To here
}

UI'yi veritabanına bağlama

Kullanıcının Ziyaretçi Defterine eklemek istediği metni girebileceği bir kullanıcı arayüzünüz var ve girişi Cloud Firestore'a eklemek için kodunuz var. Şimdi yapmanız gereken tek şey ikisini birbirine bağlamak. In lib/main.dart aşağıdaki değişiklik HomePage widget.

lib/main.dart

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Firebase Meetup'),
      ),
      body: ListView(
        children: <Widget>[
          Image.asset('assets/codelab.png'),
          const SizedBox(height: 8),
          const IconAndDetail(Icons.calendar_today, 'October 30'),
          const IconAndDetail(Icons.location_city, 'San Francisco'),
          Consumer<ApplicationState>(
            builder: (context, appState, _) => Authentication(
              email: appState.email,
              loginState: appState.loginState,
              startLoginFlow: appState.startLoginFlow,
              verifyEmail: appState.verifyEmail,
              signInWithEmailAndPassword: appState.signInWithEmailAndPassword,
              cancelRegistration: appState.cancelRegistration,
              registerAccount: appState.registerAccount,
              signOut: appState.signOut,
            ),
          ),
          const Divider(
            height: 8,
            thickness: 1,
            indent: 8,
            endIndent: 8,
            color: Colors.grey,
          ),
          const Header("What we'll be doing"),
          const Paragraph(
            'Join us for a day full of Firebase Workshops and Pizza!',
          ),
          // Modify from here
          Consumer<ApplicationState>(
            builder: (context, appState, _) => Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                if (appState.loginState == ApplicationLoginState.loggedIn) ...[
                  const Header('Discussion'),
                  GuestBook(
                    addMessage: (message) =>
                        appState.addMessageToGuestBook(message),
                  ),
                ],
              ],
            ),
          ),
          // To here.
        ],
      ),
    );
  }
}

Bu adımın başında eklediğiniz iki satırı tam uygulama ile değiştirdiniz. Yine kullandığınız Consumer<ApplicationState> Eğer render edilir ağacının bir bölümüne uygulama devlet kullanılabilir hale getirmek için. Bu, kullanıcı arayüzüne mesaj giren birine tepki vermenizi ve bunu veritabanında yayınlamanızı sağlar. Bir sonraki bölümde, eklenen mesajların veritabanında yayınlanıp yayınlanmadığını test edeceksiniz.

Mesaj göndermeyi test et

  1. Uygulamada oturum açtığınızdan emin olun.
  2. Örneğin "Hey!" Gibi bir mesaj girin ve GÖNDER düğmesini tıklayın.

Bu eylem, mesajı Cloud Firestore veritabanınıza yazar. Ancak, yine de verileri almayı uygulamanız gerektiğinden, mesajı gerçek Flutter uygulamanızda görmezsiniz. Bunu bir sonraki adımda yapacaksınız.

Ancak yeni eklenen mesajı Firebase konsolunda görebilirsiniz.

Firebase konsolunda içindeki Veritabanı pano görmeniz gerekir guestbook Yeni eklenen mesajla koleksiyonu. Mesaj göndermeye devam ederseniz, ziyaretçi defteri koleksiyonunuz aşağıdaki gibi birçok belge içerecektir:

Firebase konsolu

713870af0b3b63c.png

7. Mesajları okuyun

Konukların veri tabanına mesaj yazabilmeleri çok hoş, ancak henüz uygulamada göremiyorlar. Hadi düzeltelim!

Mesajları senkronize et

Mesajları görüntülemek için, veriler değiştiğinde tetiklenen dinleyiciler eklemeniz ve ardından yeni mesajları gösteren bir UI öğesi oluşturmanız gerekir. Uygulamadan yeni eklenen mesajları dinleyen uygulama durumuna kod ekleyeceksiniz.

Yukarıdaki GuestBook aşağıdaki değer sınıfını tarihinde eklendi. Bu sınıf, Cloud Firestore'da depoladığınız verilerin yapılandırılmış bir görünümünü sunar.

lib/main.dart

class GuestBookMessage {
  GuestBookMessage({required this.name, required this.message});
  final String name;
  final String message;
}

Bölümünde, ApplicationState Eğer devlet ve alıcılar tanımlamak, aşağıdaki yeni satırları ekleyin:

lib/main.dart

  ApplicationLoginState _loginState = ApplicationLoginState.loggedOut;
  ApplicationLoginState get loginState => _loginState;

  String? _email;
  String? get email => _email;

  // Add from here
  StreamSubscription<QuerySnapshot>? _guestBookSubscription;
  List<GuestBookMessage> _guestBookMessages = [];
  List<GuestBookMessage> get guestBookMessages => _guestBookMessages;
  // to here.

Ve son olarak, başlatma bölümündeki ApplicationState , bir kullanıcı giriş yapar ve abonelikten onlar oturumu ne zaman belge koleksiyonu üzerinde bir sorguya abone aşağıdakileri ekleyin.

lib/main.dart

  Future<void> init() async {
    await Firebase.initializeApp(
      options: DefaultFirebaseOptions.currentPlatform,
    );

    FirebaseAuth.instance.userChanges().listen((user) {
      if (user != null) {
        _loginState = ApplicationLoginState.loggedIn;
        // Add from here
        _guestBookSubscription = FirebaseFirestore.instance
            .collection('guestbook')
            .orderBy('timestamp', descending: true)
            .snapshots()
            .listen((snapshot) {
          _guestBookMessages = [];
          for (final document in snapshot.docs) {
            _guestBookMessages.add(
              GuestBookMessage(
                name: document.data()['name'] as String,
                message: document.data()['text'] as String,
              ),
            );
          }
          notifyListeners();
        });
        // to here.
      } else {
        _loginState = ApplicationLoginState.loggedOut;
        // Add from here
        _guestBookMessages = [];
        _guestBookSubscription?.cancel();
        // to here.
      }
      notifyListeners();
    });
  }

Bu bölüm olarak burada, önemli olan sen üzerinde sorgulama inşa nerede guestbook koleksiyonu ve sap abone olduğunu ve bu koleksiyona aboneliği iptal. Sen mesajların yerel önbelleğini yeniden dere, dinlemek guestbook koleksiyonu ve daha sonra ondan abonelikten böylece de bu abonelik başvuru depolar. Burada çok şey oluyor ve ne zaman daha net bir zihinsel model elde edileceğini incelemek için bir hata ayıklayıcıda biraz zaman harcamaya değer.

Daha fazla bilgi için, bkz Bulut Firestore belgelerine .

Gelen GuestBook kullanıcı arayüzünde bu değişen durumunu bağlamanız gerekir widget'tır. Widget'ı, yapılandırmasının bir parçası olarak bir mesaj listesi ekleyerek değiştirirsiniz.

lib/main.dart

class GuestBook extends StatefulWidget {
  // Modify the following line
  const GuestBook({required this.addMessage, required this.messages});
  final FutureOr<void> Function(String message) addMessage;
  final List<GuestBookMessage> messages; // new

  @override
  _GuestBookState createState() => _GuestBookState();
}

Sonra, bu yeni yapılandırmayı maruz _GuestBookState değiştirerek build şöyle yöntemi.

lib/main.dart

class _GuestBookState extends State<GuestBook> {
  final _formKey = GlobalKey<FormState>(debugLabel: '_GuestBookState');
  final _controller = TextEditingController();

  @override
  // Modify from here
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        // to here.
        Padding(
          padding: const EdgeInsets.all(8.0),
          child: Form(
            key: _formKey,
            child: Row(
              children: [
                Expanded(
                  child: TextFormField(
                    controller: _controller,
                    decoration: const InputDecoration(
                      hintText: 'Leave a message',
                    ),
                    validator: (value) {
                      if (value == null || value.isEmpty) {
                        return 'Enter your message to continue';
                      }
                      return null;
                    },
                  ),
                ),
                const SizedBox(width: 8),
                StyledButton(
                  onPressed: () async {
                    if (_formKey.currentState!.validate()) {
                      await widget.addMessage(_controller.text);
                      _controller.clear();
                    }
                  },
                  child: Row(
                    children: const [
                      Icon(Icons.send),
                      SizedBox(width: 4),
                      Text('SEND'),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
        // Modify from here
        const SizedBox(height: 8),
        for (var message in widget.messages)
          Paragraph('${message.name}: ${message.message}'),
        const SizedBox(height: 8),
      ],
      // to here.
    );
  }
}

Bir ile inşa yönteminin önceki içeriği sarmak Column kuyruk widget'te ve Column bir ekleme 'ın çocukları için koleksiyon yeni oluşturmak için Paragraph mesajlarının listedeki her bir mesaj için.

Son olarak, artık gövdesini güncellemeniz gerekir HomePage doğru inşa etmek GuestBook yeni olan messages parametresi.

lib/main.dart

Consumer<ApplicationState>(
  builder: (context, appState, _) => Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      if (appState.loginState == ApplicationLoginState.loggedIn) ...[
        const Header('Discussion'),
        GuestBook(
          addMessage: (message) =>
              appState.addMessageToGuestBook(message),
          messages: appState.guestBookMessages, // new
        ),
      ],
    ],
  ),
),

Mesajları senkronize etmeyi test edin

Cloud Firestore, verileri veritabanına abone olan istemcilerle otomatik olarak ve anında senkronize eder.

  1. Veritabanında daha önce oluşturduğunuz mesajlar uygulamada görüntülenmelidir. Yeni mesajlar yazmaktan çekinmeyin; anında görünmelidirler.
  2. Çalışma alanınızı birden çok pencerede veya sekmede açarsanız, mesajlar sekmeler arasında gerçek zamanlı olarak eşitlenir.
  3. (Opsiyonel), silme, değiştirme veya Firebase konsolunun Veritabanı bölümünde doğrudan yeni mesajlar manuel olarak eklemek deneyebilirsiniz; herhangi bir değişiklik kullanıcı arayüzünde görünmelidir.

Tebrikler! Uygulamanızda Cloud Firestore belgelerini okuyorsunuz!

Uygulama p yorumu

8. Temel güvenlik kurallarını ayarlayın

Başlangıçta Cloud Firestore'u test modunu kullanacak şekilde ayarladınız; bu, veritabanınızın okuma ve yazma işlemlerine açık olduğu anlamına gelir. Ancak test modunu yalnızca geliştirmenin çok erken aşamalarında kullanmalısınız. En iyi uygulama olarak, uygulamanızı geliştirirken veritabanınız için güvenlik kuralları oluşturmalısınız. Güvenlik, uygulamanızın yapısı ve davranışının ayrılmaz bir parçası olmalıdır.

Güvenlik Kuralları, veritabanınızdaki belgelere ve koleksiyonlara erişimi denetlemenize olanak tanır. Esnek kurallar sözdizimi, tüm veritabanına tüm yazmalardan belirli bir belgedeki işlemlere kadar her şeyle eşleşen kurallar oluşturmanıza olanak tanır.

Firebase konsolunda Cloud Firestore için güvenlik kuralları yazabilirsiniz:

  1. Firebase konsolunun geliştirin bölümünde, veritabanı tıklatın ve sonra Kuralları sekmesini seçin (veya buraya tıklayın Kuralları sekmesi doğrudan gitmek için).
  2. Kuralların herkese açık olduğuna dair bir uyarıyla birlikte aşağıdaki varsayılan güvenlik kurallarını görmelisiniz.

7767a2d2e64e7275.png

Koleksiyonları tanımlayın

İlk olarak, uygulamanın veri yazdığı koleksiyonları tanımlayın.

In match /databases/{database}/documents , korumak istediğiniz o koleksiyonunu tanımlamak:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /guestbook/{entry} {
     // You'll add rules here in the next step.
  }
}

Güvenlik kuralları ekle

Her konuk defteri belgesinde bir alan olarak Kimlik Doğrulama UID'sini kullandığınız için, Kimlik Doğrulama UID'sini alabilir ve belgeye yazmaya çalışan herkesin eşleşen bir Kimlik Doğrulama UID'si olduğunu doğrulayabilirsiniz.

Aşağıda gösterildiği gibi okuma ve yazma kurallarını kural kümenize ekleyin:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /guestbook/{entry} {
      allow read: if request.auth.uid != null;
      allow write:
        if request.auth.uid == request.resource.data.userId;
    }
  }
}

Şimdi, ziyaretçi defteri için, yalnızca oturum açmış kullanıcılar mesajları okuyabilir (herhangi bir mesaj!), ancak yalnızca bir mesajın yazarı bir mesajı düzenleyebilir.

Doğrulama kuralları ekle

Belgede beklenen tüm alanların mevcut olduğundan emin olmak için veri doğrulaması ekleyin:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /guestbook/{entry} {
      allow read: if request.auth.uid != null;
      allow write:
      if request.auth.uid == request.resource.data.userId
          && "name" in request.resource.data
          && "text" in request.resource.data
          && "timestamp" in request.resource.data;
    }
  }
}

9. Bonus adım: Öğrendiklerinizi uygulayın

Bir katılımcının LCV durumunu kaydedin

Şu anda uygulamanız, etkinlikle ilgilenen kişilerin sohbet etmeye başlamasına izin veriyor. Ayrıca, birinin gelip gelmediğini anlamanın tek yolu, onu sohbette yayınlamasıdır. Organize olalım ve kaç kişinin geleceğini insanlara bildirelim.

Uygulama durumuna birkaç yeni yetenek ekleyeceksiniz. Birincisi, oturum açmış bir kullanıcının katılıp katılmadıklarını aday gösterme yeteneğidir. İkinci yetenek, gerçekte kaç kişinin katıldığının bir sayacıdır.

In lib/main.dart , bu devlet ile etkileşim UI kodu etkinleştirmek için erişimcileri bölümüne aşağıdakileri ekleyin:

lib/main.dart

int _attendees = 0;
int get attendees => _attendees;

Attending _attending = Attending.unknown;
StreamSubscription<DocumentSnapshot>? _attendingSubscription;
Attending get attending => _attending;
set attending(Attending attending) {
  final userDoc = FirebaseFirestore.instance
      .collection('attendees')
      .doc(FirebaseAuth.instance.currentUser!.uid);
  if (attending == Attending.yes) {
    userDoc.set(<String, dynamic>{'attending': true});
  } else {
    userDoc.set(<String, dynamic>{'attending': false});
  }
}

Güncelleme ApplicationState 'ın init yöntemi aşağıdaki gibi:

lib/main.dart

  Future<void> init() async {
    await Firebase.initializeApp(
      options: DefaultFirebaseOptions.currentPlatform,
    );

    // Add from here
    FirebaseFirestore.instance
        .collection('attendees')
        .where('attending', isEqualTo: true)
        .snapshots()
        .listen((snapshot) {
      _attendees = snapshot.docs.length;
      notifyListeners();
    });
    // To here

    FirebaseAuth.instance.userChanges().listen((user) {
      if (user != null) {
        _loginState = ApplicationLoginState.loggedIn;
        _guestBookSubscription = FirebaseFirestore.instance
            .collection('guestbook')
            .orderBy('timestamp', descending: true)
            .snapshots()
            .listen((snapshot) {
          _guestBookMessages = [];
          for (final document in snapshot.docs) {
            _guestBookMessages.add(
              GuestBookMessage(
                name: document.data()['name'] as String,
                message: document.data()['text'] as String,
              ),
            );
          }
          notifyListeners();
        });
        // Add from here
        _attendingSubscription = FirebaseFirestore.instance
            .collection('attendees')
            .doc(user.uid)
            .snapshots()
            .listen((snapshot) {
          if (snapshot.data() != null) {
            if (snapshot.data()!['attending'] as bool) {
              _attending = Attending.yes;
            } else {
              _attending = Attending.no;
            }
          } else {
            _attending = Attending.unknown;
          }
          notifyListeners();
        });
        // to here
      } else {
        _loginState = ApplicationLoginState.loggedOut;
        _guestBookMessages = [];
        _guestBookSubscription?.cancel();
        _attendingSubscription?.cancel(); // new
      }
      notifyListeners();
    });
  }

Yukarıdakiler, katılımcı sayısını bulmak için her zaman abone olunan bir sorguyu ve yalnızca bir kullanıcı oturum açtığında etkin olan ikinci bir sorguyu, kullanıcının katılıp katılmadığını öğrenmek için ekler. Sonra, sonra aşağıdaki numaralandırma ekleyin GuestBookMessage beyanı:

lib/main.dart

enum Attending { yes, no, unknown }

Şimdi eski radyo düğmeleri gibi davranan yeni bir widget tanımlayacaksınız. Ne evet ne de hayır seçili olmadan belirsiz bir durumda başlar, ancak kullanıcı katılıp katılmayacağını seçtiğinde, o seçeneği dolu bir düğmeyle vurgulanmış olarak gösterirsiniz ve diğer seçenek düz bir işleme ile geri çekilir.

lib/main.dart

class YesNoSelection extends StatelessWidget {
  const YesNoSelection({required this.state, required this.onSelection});
  final Attending state;
  final void Function(Attending selection) onSelection;

  @override
  Widget build(BuildContext context) {
    switch (state) {
      case Attending.yes:
        return Padding(
          padding: const EdgeInsets.all(8.0),
          child: Row(
            children: [
              ElevatedButton(
                style: ElevatedButton.styleFrom(elevation: 0),
                onPressed: () => onSelection(Attending.yes),
                child: const Text('YES'),
              ),
              const SizedBox(width: 8),
              TextButton(
                onPressed: () => onSelection(Attending.no),
                child: const Text('NO'),
              ),
            ],
          ),
        );
      case Attending.no:
        return Padding(
          padding: const EdgeInsets.all(8.0),
          child: Row(
            children: [
              TextButton(
                onPressed: () => onSelection(Attending.yes),
                child: const Text('YES'),
              ),
              const SizedBox(width: 8),
              ElevatedButton(
                style: ElevatedButton.styleFrom(elevation: 0),
                onPressed: () => onSelection(Attending.no),
                child: const Text('NO'),
              ),
            ],
          ),
        );
      default:
        return Padding(
          padding: const EdgeInsets.all(8.0),
          child: Row(
            children: [
              StyledButton(
                onPressed: () => onSelection(Attending.yes),
                child: const Text('YES'),
              ),
              const SizedBox(width: 8),
              StyledButton(
                onPressed: () => onSelection(Attending.no),
                child: const Text('NO'),
              ),
            ],
          ),
        );
    }
  }
}

Ardından güncellemek gerekir HomePage yararlanmak için 's yapı yöntemi YesNoSelection , devam ettikleri takdirde aday gösterme kullanıcı oturum sağlayan. Ayrıca bu etkinlik için katılımcı sayısını da göstereceksiniz.

lib/main.dart

Consumer<ApplicationState>(
  builder: (context, appState, _) => Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      // Add from here
      if (appState.attendees >= 2)
        Paragraph('${appState.attendees} people going')
      else if (appState.attendees == 1)
        const Paragraph('1 person going')
      else
        const Paragraph('No one going'),
      // To here.
      if (appState.loginState == ApplicationLoginState.loggedIn) ...[
        // Add from here
        YesNoSelection(
          state: appState.attending,
          onSelection: (attending) => appState.attending = attending,
        ),
        // To here.
        const Header('Discussion'),
        GuestBook(
          addMessage: (message) =>
              appState.addMessageToGuestBook(message),
          messages: appState.guestBookMessages,
        ),
      ],
    ],
  ),
),

Kural ekle

Halihazırda ayarlanmış bazı kurallarınız olduğundan, düğmelerle eklediğiniz yeni veriler reddedilecektir. Sen ekleyerek sağlayan kuralları güncellemeniz gerekir attendees koleksiyonu.

İçin attendees , doküman adı olarak Doğrulama UID kullanılan beri koleksiyonu, sen yakala ve gönderenin doğrulayabilirsiniz uid yazdıkları belgesi olarak aynıdır. Herkesin katılımcı listesini okumasına izin vereceksiniz (orada özel veri olmadığından), ancak yalnızca içerik oluşturucu onu güncelleyebilmelidir.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // ... //
    match /attendees/{userId} {
      allow read: if true;
      allow write: if request.auth.uid == userId;
    }
  }
}

Doğrulama kuralları ekle

Belgede beklenen tüm alanların mevcut olduğundan emin olmak için veri doğrulaması ekleyin:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // ... //
    match /attendees/{userId} {
      allow read: if true;
      allow write: if request.auth.uid == userId
          && "attending" in request.resource.data;

    }
  }
}

(İsteğe bağlı) Artık düğmeleri tıklayarak sonuçlarını görebilirsiniz. Firebase konsolunda Cloud Firestore kontrol panelinize gidin.

Uygulama önizlemesi

10. Tebrikler!

Etkileşimli, gerçek zamanlı bir web uygulaması oluşturmak için Firebase'i kullandınız!

Neyi kapsadık

  • Firebase Kimlik Doğrulaması
  • Bulut Firestore
  • Firebase Güvenlik Kuralları

Sonraki adımlar

  • Diğer Firebase ürünleri hakkında daha fazla bilgi edinmek ister misiniz? Belki de kullanıcıların yüklediği resim dosyalarını saklamak istiyorsunuz? Veya kullanıcılarınıza bildirim göndermek mi? Check out Firebase belgelerine . Firebase için Flutter eklentileri hakkında daha fazla bilgi edinmek ister misiniz? Check out FlutterFire fazla bilgi için.
  • Cloud Firestore hakkında daha fazla bilgi edinmek ister misiniz? Belki alt koleksiyonlar ve işlemler hakkında bilgi edinmek istersiniz? Başının üzerinde Bulut Firestore web codelab Bulut Firestore ilgili ayrıntılı bilgileri daha giden bir codelab için. Ya da bu kontrol Bulut FireStore tanımak için YouTube serisi !

Daha fazla bilgi edin

Nasıl gitti?

Geri bildiriminizi çok isteriz! (Çok) kısa formu doldurun burada .