Firebase for Flutter'ı tanıyın

1. Başlamadan önce

Bu codelab'de Android ve iOS için Flutter mobil uygulamaları oluşturmaya yönelik Firebase'in bazı temel bilgilerini öğreneceksiniz.

Önkoşullar

Ne öğreneceksin

  • Flutter ile Android, iOS, Web ve macOS'ta etkinlik RSVP'si ve ziyaretçi defteri sohbet uygulaması nasıl oluşturulur?
  • Firebase Authentication ile kullanıcıların kimlikleri nasıl doğrulanır ve veriler Firestore ile nasıl senkronize edilir?

Android'deki uygulamanın ana ekranı

iOS'ta uygulamanın ana ekranı

İhtiyacınız olan şey

Aşağıdaki cihazlardan herhangi biri:

  • Bilgisayarınıza bağlı ve geliştirici moduna ayarlanmış fiziksel bir Android veya iOS cihazı.
  • iOS simülatörü ( Xcode araçları gerektirir).
  • Android emülatörü ( Android Studio'da kurulum gerektirir).

Ayrıca aşağıdakilere de ihtiyacınız var:

  • Google Chrome gibi seçtiğiniz bir tarayıcı.
  • Android Studio veya Visual Studio Code gibi Dart ve Flutter eklentileriyle yapılandırılmış, seçtiğiniz bir IDE veya metin düzenleyici.
  • Sınırda yaşamaktan hoşlanıyorsanız Flutter'ın en son stable sürümü veya beta .
  • Firebase projenizin oluşturulması ve yönetimi için bir Google Hesabı.
  • Firebase CLI, Google Hesabınıza giriş yaptı.

2. Örnek kodu alın

Projenizin ilk sürümünü GitHub'dan indirin:

  1. Komut satırından GitHub deposunu flutter-codelabs dizinine kopyalayın:
git clone https://github.com/flutter/codelabs.git flutter-codelabs

flutter-codelabs dizini, bir codelab koleksiyonunun kodunu içerir. Bu codelab'in kodu flutter-codelabs/firebase-get-to-know-flutter dizinindedir. Dizin, projenizin her adımın sonunda nasıl görünmesi gerektiğini gösteren bir dizi anlık görüntü içerir. Mesela ikinci adımdasınız.

  1. İkinci adım için eşleşen dosyaları bulun:
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

  • Tercih ettiğiniz IDE'de flutter-codelabs/firebase-get-to-know-flutter/step_02 dizinini açın veya içe aktarın. Bu dizin, henüz işlevsel olmayan bir Flutter buluşma uygulamasından oluşan codelab'in başlangıç ​​kodunu içerir.

Çalışması gereken dosyaları bulun

Bu uygulamadaki kod birden fazla dizine yayılmıştır. Bu işlevsellik ayrımı, kodu işlevselliğe göre gruplandırdığından işi kolaylaştırır.

  • Aşağıdaki dosyaları bulun:
    • lib/main.dart : Bu dosya ana giriş noktasını ve uygulama widget'ını içerir.
    • lib/home_page.dart : Bu dosya ana sayfa widget'ını içerir.
    • lib/src/widgets.dart : Bu dosya, uygulamanın stilini standartlaştırmaya yardımcı olacak bir avuç widget içerir. Başlangıç ​​uygulamasının ekranını oluştururlar.
    • lib/src/authentication.dart : Bu dosya, Firebase e-posta tabanlı kimlik doğrulaması için oturum açma kullanıcı deneyimi oluşturmak amacıyla bir dizi widget içeren Kimlik Doğrulamanın kısmi bir uygulamasını içerir. Kimlik doğrulama akışına yönelik bu widget'lar henüz başlangıç ​​uygulamasında kullanılmıyor ancak yakında ekleyeceksiniz.

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

lib/main.dart dosyasını inceleyin

Bu uygulama, Roboto'yu uygulama genelinde varsayılan yazı tipi yapmak için google_fonts paketinden yararlanır. Fonts.google.com'u keşfedebilir ve orada bulduğunuz yazı tiplerini uygulamanın farklı bölümlerinde kullanabilirsiniz.

lib/src/widgets.dart dosyasındaki yardımcı widget'ları Header , Paragraph ve IconAndDetail biçiminde kullanırsınız. Bu widget'lar, HomePage açıklanan sayfa düzenindeki dağınıklığı azaltmak için yinelenen kodları ortadan kaldırır. Bu aynı zamanda tutarlı bir görünüm ve his sağlar.

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

Android'deki uygulamanın ana ekranı

iOS'ta uygulamanın ana ekranı

Uygulamanın web'deki ana ekranı

MacOS'ta uygulamanın ana ekranı

3. Firebase projesi oluşturun ve yapılandırın

Etkinlik bilgilerinin görüntülenmesi misafirleriniz için harikadır ancak tek başına hiç kimse için pek yararlı değildir. Uygulamaya bazı dinamik işlevler eklemeniz gerekir. Bunu yapmak için Firebase'i uygulamanıza bağlamanız gerekir. Firebase'i kullanmaya başlamak için bir Firebase projesi oluşturup yapılandırmanız gerekir.

Firebase projesi oluşturma

  1. Firebase'de oturum açın.
  2. Konsolda Proje Ekle veya Proje oluştur'u tıklayın.
  3. Proje adı alanına Firebase-Flutter-Codelab girin ve ardından Devam'a tıklayın.

4395e4e67c08043a.png

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

b7138cde5f2c7b61.png

Firebase projeleri hakkında daha fazla bilgi edinmek için Firebase projelerini anlama konusuna bakın.

Uygulama, web uygulamaları için kullanılabilen aşağıdaki Firebase ürünlerini kullanır:

  • Kimlik Doğrulama: Kullanıcıların uygulamanızda oturum açmasına olanak tanır.
  • Firestore: Yapılandırılmış verileri buluta kaydeder ve veriler değiştiğinde anında bildirim alır.
  • Firebase Güvenlik Kuralları: Veritabanınızı korur.

Bu ürünlerden bazılarının özel konfigürasyona ihtiyacı vardır veya bunları Firebase konsolunda etkinleştirmeniz gerekir.

E-postayla oturum açma kimlik doğrulamasını etkinleştir

  1. Firebase konsolunun Projeye genel bakış bölmesinde Oluştur menüsünü genişletin.
  2. Kimlik Doğrulama > Başlarken > Oturum açma yöntemi > E-posta/Parola > Etkinleştir > Kaydet öğesine tıklayın.

58e3e3e23c2f16a4.png

Firestore'u etkinleştir

Web uygulaması, sohbet mesajlarını kaydetmek ve yeni sohbet mesajları almak için Firestore'u kullanır.

Firestore'u etkinleştirin:

  • Oluştur menüsünde Firestore Veritabanı > Veritabanı oluştur öğesine tıklayın.

99e8429832d23fa3.png

  1. Test modunda başlat'ı seçin ve ardından güvenlik kurallarıyla ilgili sorumluluk reddi beyanını okuyun. Test modu, geliştirme sırasında veritabanına serbestçe yazabilmenizi sağlar.

6be00e26c72ea032.png

  1. İleri'ye tıklayın ve ardından veritabanınızın konumunu seçin. Varsayılanı kullanabilirsiniz. Konumu daha sonra değiştiremezsiniz.

278656eefcfb0216.png

  1. Etkinleştir'i tıklayın.

4. Firebase'i yapılandırın

Firebase'i Flutter ile kullanmak için Flutter projesini FlutterFire kitaplıklarını doğru kullanacak şekilde yapılandırmak üzere aşağıdaki görevleri tamamlamanız gerekir:

  1. FlutterFire bağımlılıklarını projenize ekleyin.
  2. İstediğiniz platformu Firebase projesine kaydedin.
  3. Platforma özel yapılandırma dosyasını indirin ve ardından koda ekleyin.

Flutter uygulamanızın üst düzey dizininde sırasıyla iOS ve Android için platforma özel konfigürasyon dosyalarını barındıran android , ios , macos ve web alt dizinleri bulunmaktadır.

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

Bu uygulamada kullandığınız iki Firebase ürünü için FlutterFire kitaplıklarını eklemeniz gerekir: Authentication ve Firestore.

  • Komut satırından aşağıdaki bağımlılıkları ekleyin:
$ flutter pub add firebase_core

firebase_core paketi, tüm Firebase Flutter eklentileri için gereken ortak koddur.

$ flutter pub add firebase_auth

firebase_auth paketi Kimlik Doğrulama ile entegrasyonu sağlar.

$ flutter pub add cloud_firestore

cloud_firestore paketi, Firestore veri depolama alanına erişim sağlar.

$ flutter pub add provider

firebase_ui_auth paketi, kimlik doğrulama akışlarıyla geliştirici hızını artırmak için bir dizi widget ve yardımcı program sağlar.

$ flutter pub add firebase_ui_auth

Gerekli paketleri eklediniz ancak Firebase'i uygun şekilde kullanmak için iOS, Android, macOS ve Web runner projelerini de yapılandırmanız gerekiyor. Ayrıca iş mantığının ekran mantığından ayrılmasını sağlayan provider paketini de kullanırsınız.

FlutterFire CLI'yi yükleyin

FlutterFire CLI, temeldeki Firebase CLI'ye bağlıdır.

  1. Henüz yapmadıysanız makinenize Firebase CLI'yi yükleyin.
  2. FlutterFire CLI'yi yükleyin:
$ dart pub global activate flutterfire_cli

flutterfire komutu kurulduktan sonra dünya çapında kullanılabilir.

Uygulamalarınızı yapılandırın

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

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

$ flutterfire configure

Yapılandırma komutu aşağıdaki işlemlerde size yol gösterir:

  1. .firebaserc dosyasına dayalı olarak veya Firebase Konsolundan bir Firebase projesi seçin.
  2. Yapılandırma için Android, iOS, macOS ve web gibi platformları belirleyin.
  3. Yapılandırmanın çıkarılacağı Firebase uygulamalarını belirleyin. Varsayılan olarak CLI, Firebase uygulamalarını mevcut proje yapılandırmanıza göre 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ı alana alınmış uygulamalar oluşturur. Bu uygulama, Firebase sunucularıyla iletişim kurmak için ağla entegre olduğundan, uygulamanızı ağ istemci ayrıcalıklarıyla yapılandırmanız gerekir.

macos/Runner/DebugProfile.entitlements

<?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.entitlements

<?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>

Daha fazla bilgi için bkz. Flutter için Masaüstü desteği .

5. RSVP işlevini ekleyin

Artık Firebase'i uygulamaya eklediğinize göre, kişileri Kimlik Doğrulama ile kaydeden bir RSVP düğmesi oluşturabilirsiniz. Android yerel, iOS yerel ve Web için önceden oluşturulmuş FirebaseUI Auth paketleri vardır, ancak bu özelliği Flutter için oluşturmanız gerekir.

Daha önce aldığınız proje, kimlik doğrulama akışının çoğu için kullanıcı arayüzünü uygulayan bir dizi widget içeriyordu. Kimlik Doğrulamayı uygulamayla entegre etmek için iş mantığını uygularsınız.

Provider paketiyle iş mantığı ekleyin

Uygulamanın Flutter widget'ları ağacında merkezi bir uygulama durumu nesnesinin kullanılabilir olmasını sağlamak için provider paketini kullanın:

  1. Aşağıdaki içeriğe sahip app_state.dart adlı yeni bir dosya oluşturun:

lib/app_state.dart

import 'package:firebase_auth/firebase_auth.dart'
    hide EmailAuthProvider, PhoneAuthProvider;
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';

import 'firebase_options.dart';

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

  bool _loggedIn = false;
  bool get loggedIn => _loggedIn;

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

    FirebaseUIAuth.configureProviders([
      EmailAuthProvider(),
    ]);

    FirebaseAuth.instance.userChanges().listen((user) {
      if (user != null) {
        _loggedIn = true;
      } else {
        _loggedIn = false;
      }
      notifyListeners();
    });
  }
}

import ifadeleri Firebase Core ve Auth'u tanıtır, uygulama durumu nesnesini widget ağacında kullanılabilir hale getiren provider paketini çeker ve firebase_ui_auth paketindeki kimlik doğrulama widget'larını içerir.

Bu ApplicationState uygulama durumu nesnesinin bu adım için bir ana sorumluluğu vardır; bu, widget ağacını, kimliği doğrulanmış bir duruma yönelik bir güncelleme olduğu konusunda uyarmaktır.

Bir sağlayıcıyı yalnızca kullanıcının oturum açma durumunun durumunu uygulamaya iletmek için kullanırsınız. Bir kullanıcının oturum açmasına izin vermek için firebase_ui_auth paketi tarafından sağlanan kullanıcı arayüzlerini kullanırsınız; bu, uygulamalarınızdaki oturum açma ekranlarını hızlı bir şekilde önyüklemenin harika bir yoludur.

Kimlik doğrulama akışını entegre edin

  1. İçe aktarma işlemlerini lib/main.dart dosyasının üst kısmında değiştirin:

lib/main.dart

import 'package:firebase_ui_auth/firebase_ui_auth.dart'; // new
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';               // new
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';                 // new

import 'app_state.dart';                                 // new
import 'home_page.dart';
  1. Uygulama durumunu uygulama başlatma işlemine bağlayın ve ardından kimlik doğrulama akışını HomePage ekleyin:

lib/main.dart

void main() {
  // Modify from here...
  WidgetsFlutterBinding.ensureInitialized();

  runApp(ChangeNotifierProvider(
    create: (context) => ApplicationState(),
    builder: ((context, child) => const App()),
  ));
  // ...to here.
}

main() işlevinde yapılan değişiklik, sağlayıcı paketini ChangeNotifierProvider widget'ıyla uygulama durumu nesnesinin başlatılmasından sorumlu kılar. Bu özel provider sınıfını kullanırsınız çünkü uygulama durumu nesnesi, provider paketinin bağımlı pencere öğelerini ne zaman yeniden görüntüleyeceğini bilmesini sağlayan ChangeNotifier sınıfını genişletir.

  1. Bir GoRouter yapılandırması oluşturarak, FirebaseUI'nin size sağladığı farklı ekranlarda gezinmeyi yönetecek şekilde uygulamanızı güncelleyin:

lib/main.dart

// Add GoRouter configuration outside the App class
final _router = GoRouter(
  routes: [
    GoRoute(
      path: '/',
      builder: (context, state) => const HomePage(),
      routes: [
        GoRoute(
          path: 'sign-in',
          builder: (context, state) {
            return SignInScreen(
              actions: [
                ForgotPasswordAction(((context, email) {
                  final uri = Uri(
                    path: '/sign-in/forgot-password',
                    queryParameters: <String, String?>{
                      'email': email,
                    },
                  );
                  context.push(uri.toString());
                })),
                AuthStateChangeAction(((context, state) {
                  final user = switch (state) {
                    SignedIn state => state.user,
                    UserCreated state => state.credential.user,
                    _ => null
                  };
                  if (user == null) {
                    return;
                  }
                  if (state is UserCreated) {
                    user.updateDisplayName(user.email!.split('@')[0]);
                  }
                  if (!user.emailVerified) {
                    user.sendEmailVerification();
                    const snackBar = SnackBar(
                        content: Text(
                            'Please check your email to verify your email address'));
                    ScaffoldMessenger.of(context).showSnackBar(snackBar);
                  }
                  context.pushReplacement('/');
                })),
              ],
            );
          },
          routes: [
            GoRoute(
              path: 'forgot-password',
              builder: (context, state) {
                final arguments = state.uri.queryParameters;
                return ForgotPasswordScreen(
                  email: arguments['email'],
                  headerMaxExtent: 200,
                );
              },
            ),
          ],
        ),
        GoRoute(
          path: 'profile',
          builder: (context, state) {
            return ProfileScreen(
              providers: const [],
              actions: [
                SignedOutAction((context) {
                  context.pushReplacement('/');
                }),
              ],
            );
          },
        ),
      ],
    ),
  ],
);
// end of GoRouter configuration

// Change MaterialApp to MaterialApp.router and add the routerConfig
class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: 'Firebase Meetup',
      theme: ThemeData(
        buttonTheme: Theme.of(context).buttonTheme.copyWith(
              highlightColor: Colors.deepPurple,
            ),
        primarySwatch: Colors.deepPurple,
        textTheme: GoogleFonts.robotoTextTheme(
          Theme.of(context).textTheme,
        ),
        visualDensity: VisualDensity.adaptivePlatformDensity,
        useMaterial3: true,
      ),
      routerConfig: _router, // new
    );
  }
}

Her ekran, kimlik doğrulama akışının yeni durumuna bağlı olarak kendisiyle ilişkilendirilen farklı türde bir eyleme sahiptir. Kimlik doğrulamadaki çoğu durum değişikliğinden sonra, ister ana ekran ister profil gibi farklı bir ekran olsun, tercih ettiğiniz bir ekrana yeniden yönlendirebilirsiniz.

  1. HomePage sınıfının derleme yönteminde, uygulama durumunu AuthFunc widget'ıyla tümleştirin:

lib/home_page.dart

import 'package:firebase_auth/firebase_auth.dart' // new
    hide EmailAuthProvider, PhoneAuthProvider;    // new
import 'package:flutter/material.dart';           // new
import 'package:provider/provider.dart';          // new

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

class HomePage extends StatelessWidget {
  const HomePage({super.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, _) => AuthFunc(
                loggedIn: appState.loggedIn,
                signOut: () {
                  FirebaseAuth.instance.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!',
          ),
        ],
      ),
    );
  }
}

AuthFunc widget'ını başlatır ve onu bir Consumer widget'ına sararsınız. Tüketici widget'ı, uygulama durumu değiştiğinde provider paketinin ağacın bir kısmını yeniden oluşturmak için kullanılabileceği olağan yoldur. AuthFunc widget'ı, test ettiğiniz tamamlayıcı widget'lardır.

Kimlik doğrulama akışını test edin

cdf2d25e436bd48d.png

  1. Uygulamada SignInScreen başlatmak için RSVP düğmesine dokunun.

2a2cd6d69d172369.png

  1. Bir e-mail adresi girin. Zaten kayıtlıysanız sistem sizden bir şifre girmenizi ister. Aksi taktirde sistem sizden kayıt formunu doldurmanızı isteyecektir.

e5e65065dba36b54.png

  1. Hata işleme akışını kontrol etmek için altı karakterden kısa bir şifre girin. Kayıtlıysanız bunun yerine şifreyi görürsünüz.
  2. Hata işleme akışını kontrol etmek için yanlış şifreler girin.
  3. Doğru şifreyi girin. Kullanıcıya oturumu kapatma olanağı sunan oturum açma deneyimini görürsünüz.

4ed811a25b0cf816.png

6. Firestore'a mesaj yazın

Kullanıcıların geldiğini bilmek harika, ancak konuklara uygulamada yapacak başka bir şey vermeniz gerekiyor. Ya ziyaretçi defterine mesaj bırakabilselerdi? Gelmekten neden heyecan duyduklarını veya kiminle tanışmayı umduklarını paylaşabilirler.

Kullanıcıların uygulamada yazdığı sohbet mesajlarını depolamak için Firestore'u kullanırsınız.

Veri örneği

Firestore bir NoSQL veritabanıdır ve veritabanında depolanan veriler koleksiyonlara, belgelere, alanlara ve alt koleksiyonlara bölünmüştür. Sohbetin her mesajını, üst düzey bir koleksiyon olan guestbook koleksiyonunda bir belge olarak saklarsınız.

7c20dc8424bb1d84.png

Firestore'a mesaj ekleme

Bu bölümde, kullanıcıların veritabanına mesaj yazmasına yönelik işlevselliği eklersiniz. Öncelikle form alanı ve gönder butonunu ekliyorsunuz, ardından bu elemanları veritabanına bağlayan kodu ekliyorsunuz.

  1. guest_book.dart adında yeni bir dosya oluşturun, bir mesaj alanının kullanıcı arayüzü öğelerini ve bir gönder düğmesini oluşturmak için bir GuestBook durum bilgisi widget'ı ekleyin:

lib/misafir_kitabı.dart

import 'dart:async';

import 'package:flutter/material.dart';

import 'src/widgets.dart';

class GuestBook extends StatefulWidget {
  const GuestBook({required this.addMessage, super.key});

  final FutureOr<void> Function(String message) addMessage;

  @override
  State<GuestBook> 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 birkaç ilgi çekici nokta var. İlk olarak, mesajın gerçekten içerik içerdiğini doğrulayabilmeniz ve eğer içerik yoksa kullanıcıya bir hata mesajı gösterebilmeniz için bir form oluşturursunuz. Bir formu doğrulamak için formun arkasındaki form durumuna GlobalKey ile erişirsiniz. Anahtarlar ve bunların nasıl kullanılacağı hakkında daha fazla bilgi için bkz. Anahtarlar Ne Zaman Kullanılır ?

Ayrıca widget'ların düzenlenme şekline de dikkat edin; TextFormField içeren bir Row ve Row içeren bir StyledButton var. Ayrıca TextFormField öğesinin, TextFormField satırdaki fazladan boşluğu doldurmaya zorlayan Expanded bir widget'a sarıldığını da unutmayın. Bunun neden gerekli olduğunu daha iyi anlamak için bkz. Kısıtlamaları anlama.

Artık kullanıcının Ziyaretçi Defterine eklemek üzere metin girmesine olanak tanıyan bir widget'ınız olduğuna göre, onu ekrana getirmeniz gerekir.

  1. ListView alt öğelerinin sonuna aşağıdaki iki satırı eklemek için HomePage gövdesini düzenleyin:
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üncellersiniz.

Uygulama önizlemesi

Sohbet entegrasyonlu Android'deki uygulamanın ana ekranı

iOS'ta uygulamanın sohbet entegrasyonlu ana ekranı

Sohbet entegrasyonuyla uygulamanın web üzerindeki ana ekranı

Sohbet entegrasyonlu uygulamanın macOS'taki ana ekranı

Bir kullanıcı GÖNDER'i tıkladığında aşağıdaki kod parçacığı tetiklenir. Mesaj giriş alanının içeriğini veritabanının guestbook koleksiyonuna ekler. Özellikle, addMessageToGuestBook yöntemi, mesaj içeriğini guestbook koleksiyonunda otomatik olarak oluşturulan bir kimlikle yeni bir belgeye ekler.

FirebaseAuth.instance.currentUser.uid öğesinin, Kimlik Doğrulamanın oturum açmış tüm kullanıcılar için sağladığı otomatik olarak oluşturulan benzersiz kimliğe bir referans olduğunu unutmayın.

  • lib/app_state.dart dosyasına addMessageToGuestBook yöntemini ekleyin. Bir sonraki adımda bu yeteneği kullanıcı arayüzüne bağlarsınız.

lib/app_state.dart

import 'package:cloud_firestore/cloud_firestore.dart'; // new
import 'package:firebase_auth/firebase_auth.dart'
    hide EmailAuthProvider, PhoneAuthProvider;
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';

import 'firebase_options.dart';

class ApplicationState extends ChangeNotifier {

  // Current content of ApplicationState elided ...

  // Add from here...
  Future<DocumentReference> addMessageToGuestBook(String message) {
    if (!_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.
}

Kullanıcı arayüzünü ve veritabanını bağlayın

Kullanıcının Ziyaretçi Defterine eklemek istediği metni girebileceği bir kullanıcı arayüzünüz var ve girişi Firestore'a eklemek için kodunuz var. Şimdi tek yapmanız gereken ikisini birbirine bağlamak.

  • lib/home_page.dart dosyasında HomePage widget'ında aşağıdaki değişikliği yapın:

lib/home_page.dart

import 'package:firebase_auth/firebase_auth.dart'
    hide EmailAuthProvider, PhoneAuthProvider;
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import 'app_state.dart';
import 'guest_book.dart';                         // new
import 'src/authentication.dart';
import 'src/widgets.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, _) => AuthFunc(
                loggedIn: appState.loggedIn,
                signOut: () {
                  FirebaseAuth.instance.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.loggedIn) ...[
                  const Header('Discussion'),
                  GuestBook(
                    addMessage: (message) =>
                        appState.addMessageToGuestBook(message),
                  ),
                ],
              ],
            ),
          ),
          // ...to here.
        ],
      ),
    );
  }
}

Bu adımın başında eklediğiniz iki satırı tam uygulamayla değiştirdiniz. Uygulama durumunu ağacın oluşturduğunuz kısmında kullanılabilir hale getirmek için yine Consumer<ApplicationState> öğesini kullanırsınız. 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 edin

  1. Gerekirse uygulamada oturum açın.
  2. Hey there! gibi bir mesaj girin. ve ardından GÖNDER'e tıklayın.

Bu eylem, mesajı Firestore veritabanınıza yazar. Ancak gerçek Flutter uygulamanızda bu mesajı göremezsiniz çünkü bir sonraki adımda yapacağınız veri alma işlemini gerçekleştirmeniz gerekir. Ancak Firebase konsolunun Veritabanı kontrol panelinde , eklenen mesajınızı guestbook koleksiyonunda görebilirsiniz. Daha fazla mesaj gönderirseniz guestbook koleksiyonunuza daha fazla belge eklersiniz. Örneğin aşağıdaki kod parçacığına bakın:

713870af0b3b63c.png

7. Mesajları okuyun

Konukların veritabanına mesaj yazabilmesi ama bunları henüz uygulamada görememesi çok güzel. Bunu düzeltmenin zamanı geldi!

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 kullanıcı arayüzü öğesi oluşturmanız gerekir. Uygulamadan yeni eklenen mesajları dinleyen uygulama durumuna kod eklersiniz.

  1. Yeni bir guest_book_message.dart dosyası oluşturun ve Firestore'da depoladığınız verilerin yapılandırılmış bir görünümünü ortaya çıkarmak için aşağıdaki sınıfı ekleyin.

lib/guest_book_message.dart

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

  final String name;
  final String message;
}
  1. lib/app_state.dart dosyasına aşağıdaki içe aktarmaları ekleyin:

lib/app_state.dart

import 'dart:async';                                     // new

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart'
    hide EmailAuthProvider, PhoneAuthProvider;
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';

import 'firebase_options.dart';
import 'guest_book_message.dart';                        // new
  1. ApplicationState durumu ve alıcıları tanımladığınız bölümüne aşağıdaki satırları ekleyin:

lib/app_state.dart

  bool _loggedIn = false;
  bool get loggedIn => _loggedIn;

  // Add from here...
  StreamSubscription<QuerySnapshot>? _guestBookSubscription;
  List<GuestBookMessage> _guestBookMessages = [];
  List<GuestBookMessage> get guestBookMessages => _guestBookMessages;
  // ...to here.
  1. ApplicationState başlatma bölümünde, kullanıcı oturum açtığında belge koleksiyonu üzerinden bir sorguya abone olmak ve oturumu kapattığında aboneliği iptal etmek için aşağıdaki satırları ekleyin:

lib/app_state.dart

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

    FirebaseUIAuth.configureProviders([
      EmailAuthProvider(),
    ]);
    
    FirebaseAuth.instance.userChanges().listen((user) {
      if (user != null) {
        _loggedIn = true;
        _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();
        });
      } else {
        _loggedIn = false;
        _guestBookMessages = [];
        _guestBookSubscription?.cancel();
      }
      notifyListeners();
    });
  }

Bu bölüm önemlidir çünkü burası guestbook koleksiyonu üzerinde bir sorgu oluşturacağınız ve bu koleksiyona abone olma ve abonelikten çıkma işlemlerini gerçekleştireceğiniz yerdir. guestbook koleksiyonundaki mesajların yerel önbelleğini yeniden oluşturduğunuz akışı dinlersiniz ve ayrıca daha sonra aboneliğinizi iptal edebilmek için bu aboneliğe bir referans saklarsınız. Burada çok şey oluyor, bu yüzden daha net bir zihinsel model elde etmek için ne olduğunu incelemek için bunu bir hata ayıklayıcıda keşfetmelisiniz. Daha fazla bilgi için bkz. Firestore ile gerçek zamanlı güncellemeler alma .

  1. lib/guest_book.dart dosyasına aşağıdaki içe aktarmayı ekleyin:
import 'guest_book_message.dart';
  1. GuestBook widget'ına, bu değişen durumu kullanıcı arayüzüne bağlamak için yapılandırmanın bir parçası olarak bir mesaj listesi ekleyin:

lib/misafir_kitabı.dart

class GuestBook extends StatefulWidget {
  // Modify the following line:
  const GuestBook({
    super.key, 
    required this.addMessage, 
    required this.messages,
  });

  final FutureOr<void> Function(String message) addMessage;
  final List<GuestBookMessage> messages; // new

  @override
  _GuestBookState createState() => _GuestBookState();
}
  1. _GuestBookState , bu yapılandırmayı ortaya çıkarmak için build yöntemini aşağıdaki gibi değiştirin:

lib/misafir_kitabı.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.
    );
  }
}

build() yönteminin önceki içeriğini bir Column widget'ıyla sararsınız ve ardından mesaj listesindeki her mesaj için yeni bir Paragraph oluşturmak üzere Column alt öğelerinin kuyruğuna bir koleksiyon eklersiniz.

  1. GuestBook yeni messages parametresiyle doğru şekilde oluşturmak için HomePage gövdesini güncelleyin:

lib/home_page.dart

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

Test mesajı senkronizasyonu

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

Test mesajı senkronizasyonu:

  1. Uygulamada, daha önce veritabanında oluşturduğunuz mesajları bulun.
  2. Yeni mesajlar yazın. Anında görünürler.
  3. Çalışma alanınızı birden çok pencerede veya sekmede açın. Mesajlar pencereler ve sekmeler arasında gerçek zamanlı olarak senkronize edilir.
  4. İsteğe bağlı: Firebase konsolunun Veritabanı menüsünde mesajları manuel olarak silin, değiştirin veya yeni mesajlar ekleyin. Tüm değişiklikler kullanıcı arayüzünde görünür.

Tebrikler! Firestore belgelerini uygulamanızda okursunuz!

Uygulama önizlemesi

Sohbet entegrasyonlu Android'deki uygulamanın ana ekranı

iOS'ta uygulamanın sohbet entegrasyonlu ana ekranı

Sohbet entegrasyonuyla uygulamanın web üzerindeki ana ekranı

Sohbet entegrasyonlu uygulamanın macOS'taki ana ekranı

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

Başlangıçta 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 ilk aşamalarında kullanmalısınız. En iyi uygulama olarak, uygulamanızı geliştirirken veritabanınız için güvenlik kuralları ayarlamanız gerekir. Güvenlik, uygulamanızın yapısının ve davranışının ayrılmaz bir parçasıdır.

Firebase Güvenlik Kuralları, veritabanınızdaki belgelere ve koleksiyonlara erişimi kontrol etmenize olanak tanır. Esnek kural sözdizimi, veritabanının tamamına yapılan tüm yazma işlemlerinden belirli bir belgedeki işlemlere kadar her şeyi eşleştiren kurallar oluşturmanıza olanak tanır.

Temel güvenlik kurallarını ayarlayın:

  1. Firebase konsolunun Geliştir menüsünde Veritabanı > Kurallar'ı tıklayın. Aşağıdaki varsayılan güvenlik kurallarını ve kuralların herkese açık olduğuna ilişkin bir uyarı görmelisiniz:

7767a2d2e64e7275.png

  1. Uygulamanın veri yazdığı koleksiyonları tanımlayın:

match /databases/{database}/documents dosyasında, güvenliğini sağlamak istediğiniz koleksiyonu tanımlayın:

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

Kimlik Doğrulama UID'sini her ziyaretçi defteri belgesinde bir alan olarak 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'sine sahip olduğunu doğrulayabilirsiniz.

  1. 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;
    }
  }
}

Artık ziyaretçi defterindeki mesajları yalnızca oturum açmış kullanıcılar okuyabilir, ancak yalnızca mesajın yazarı bir mesajı düzenleyebilir.

  1. Beklenen tüm alanların belgede mevcut olduğundan emin olmak için veri doğrulama 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 insanların yalnızca etkinlikle ilgilendiklerinde sohbet etmesine izin veriyor. Ayrıca birisinin gelip gelmediğini bilmenin tek yolu sohbette bunu söylemesidir.

Bu adımda organize olursunuz ve kaç kişinin geleceğini insanlara bildirirsiniz. Uygulama durumuna birkaç özellik eklersiniz. Bunlardan ilki, oturum açmış bir kullanıcının katılıp katılmayacağını belirleme yeteneğidir. İkincisi ise kaç kişinin katıldığını gösteren bir sayaçtır.

  1. UI kodunun bu durumla etkileşim kurabilmesi için lib/app_state.dart dosyasında ApplicationState erişimciler bölümüne aşağıdaki satırları ekleyin:

lib/app_state.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});
  }
}
  1. ApplicationState init() yöntemini aşağıdaki gibi güncelleyin:

lib/app_state.dart

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

    FirebaseUIAuth.configureProviders([
      EmailAuthProvider(),
    ]);

    // 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) {
        _loggedIn = true;
        _emailVerified = user.emailVerified;
        _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 {
        _loggedIn = false;
        _emailVerified = false;
        _guestBookMessages = [];
        _guestBookSubscription?.cancel();
        _attendingSubscription?.cancel(); // new
      }
      notifyListeners();
    });
  }

Bu kod, katılımcı sayısını belirlemek için her zaman abone olunan bir sorgu ve kullanıcının katılıp katılmadığını belirlemek için yalnızca kullanıcı oturum açtığında etkin olan ikinci bir sorgu ekler.

  1. Aşağıdaki numaralandırmayı lib/app_state.dart dosyasının en üstüne ekleyin.

lib/app_state.dart

enum Attending { yes, no, unknown }
  1. Yeni bir yes_no_selection.dart dosyası oluşturun, radyo düğmeleri gibi davranan yeni bir widget tanımlayın:

lib/yes_no_selection.dart

import 'package:flutter/material.dart';

import 'app_state.dart';
import 'src/widgets.dart';

class YesNoSelection extends StatelessWidget {
  const YesNoSelection(
      {super.key, 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: [
              FilledButton(
                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),
              FilledButton(
                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'),
              ),
            ],
          ),
        );
    }
  }
}

Ne Evet ne de Hayır seçiliyken belirsiz bir durumda başlar. Kullanıcı katılıp katılmayacağını seçtiğinde, bu seçeneği dolu bir düğmeyle vurgulanmış olarak gösterirsiniz ve diğer seçenek düz bir görüntüyle geride kalır.

  1. YesNoSelection avantajından yararlanmak için HomePage build() yöntemini güncelleyin, oturum açmış bir kullanıcının katılıp katılmayacağını belirlemesini sağlayın ve etkinliğe katılanların sayısını görüntüleyin:

lib/home_page.dart

Consumer<ApplicationState>(
  builder: (context, appState, _) => Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      // Add from here...
      switch (appState.attendees) {
        1 => const Paragraph('1 person going'),
        >= 2 => Paragraph('${appState.attendees} people going'),
        _ => const Paragraph('No one going'),
      },
      // ...to here.
      if (appState.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

Zaten bazı kurallar ayarladınız, bu nedenle düğmelerle eklediğiniz veriler reddedilecek. attendees koleksiyonuna ekleme yapılmasına izin vermek için kuralları güncellemeniz gerekir.

  1. attendees koleksiyonunda, belge adı olarak kullandığınız Kimlik Doğrulama UID'sini alın ve gönderenin uid yazdığı belgeyle aynı olduğunu doğrulayın:
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // ... //
    match /attendees/{userId} {
      allow read: if true;
      allow write: if request.auth.uid == userId;
    }
  }
}

Bu, orada özel veri olmadığından herkesin katılımcı listesini okumasına olanak tanır, ancak listeyi yalnızca oluşturan kişi güncelleyebilir.

  1. Beklenen tüm alanların belgede mevcut olduğundan emin olmak için veri doğrulama 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;

    }
  }
}
  1. İsteğe bağlı: Uygulamada, Firebase konsolundaki Firestore kontrol panelindeki sonuçları görmek için düğmeleri tıklayın.

Uygulama önizlemesi

Android'deki uygulamanın ana ekranı

iOS'ta uygulamanın ana ekranı

Uygulamanın web'deki ana ekranı

MacOS'ta uygulamanın ana ekranı

10. Tebrikler!

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

Daha fazla bilgi edin