Osiki  Douglas

Osiki Douglas

1657005732

Next Blog Firestore | Example Of Blog Built with Next.js, Firebase

Next Blog Firestore

This blog uses Next.js for SSR & Firebase Firestore API for storing and fetching data. Create and edit your content in simple custom content management system built with React, Mobx State Tree and Styled Components.

Clone this repo and use it as starting point to create your own fancy blog.

What you get:

  • Posts feed
  • Featured posts
  • Posts by tags and category
  • Multi language support
  • Multi author support
  • Markdown with ability to use custom React components
  • Simple and convenient CMS inspired by Ghost
  • CMS is protected by Firebase Auth
  • Quick and SEO-friendly responses with SSR
  • Good results in Lighthouse

Getting started

Step 1. Create Firebase account

Create Firebase account

Step 2. Setup Authentication Method

  • Click Set up sign-in method on Authentication section.
  • Enable just Google authentication provider.
  • Add your domain (if you have one) to Authorized domains.

Setup authentication

Step 3. Create Firestore database

  • Go to Database section and create Firestore instance.

Create Firestore database

Firestore is still in beta, but it doesn't make it less awesome.

Step 4. Database configuration.

  • Go to Rules section in your database and paste configuration from .firebase-rules in project root.
  • Publish new rules.

Step 5. Set up Firebase secret keys for our app.

  • Create .env at the root of the project. Do not commit this file. It is personal data that should not be available for everyone.
  • Go to Project settings in Firebase console (click on the gear icon next to Project Overview).
  • Copy data from this page to .env in the following format:
F_PROJECT_ID=<your Project ID>
F_AUTH_DOMAIN=<your Project ID>.firebaseapp.com
F_API_KEY=<your Web API Key>

Step 6. Set up Firebase Admin SDK key for importing/exporting data from database.

In order to be able to initialize database with initial seed we need to generate private Firebase Admin service key.

  • Go to Project Settings > Service Accounts and click Generate new private key button.
  • Save downloaded file as firebase-service-key.json at project root.

** Do not commit this file. It's added to .gitignore by default.

Step 7. Initialize database with initial data.

We almost finished. Let's initialize our database with initial data.

yarn
yarn run seed

Step 8. Setup database indexes.

We need manually setup indexes in our Firestore database to be able to make REST requests to our Firebase.

  • Go to Database > Indexes and create the following index.

Create indexes

Step 9. Run blog locally.

We're ready to launch our blog locally.

yarn dev

Blog is up and running on http://localhost:3000.

Step 10. Sign in to admin part.

Wait.. But what's about CMS part?

  • Go to http://localhost:3000/admin and click on "Click to start writing".
  • Sign-in with your Google Account in popup window.
  • Go to Firebase Console and add author rights to account you just signed in with.
    • Copy User UID in Authentication section.
    • Create authors collection in Database
    • Create a record in authors collection, where documentId is UID of the user and name is id of user in config.js file.

Map author and user

Step 11. Ready to go!

Download Details:
Author: suevalov
Source Code: https://github.com/suevalov/next-blog-firestore
License: MIT license

#nextjs #react #javascript #firestore 

Next Blog Firestore | Example Of Blog Built with Next.js, Firebase

A Flutter Package to Simplify Pagination with Firestore Data

Pagination in Firestore

Setup

Use the same setup used for cloud_firestore package (or follow this).

Usage

In your pubspec.yaml

dependencies:
  paginate_firestore: # latest version

Import it

import 'package:paginate_firestore/paginate_firestore.dart';

Implement it

      PaginateFirestore(
        //item builder type is compulsory.
        itemBuilder: (context, documentSnapshots, index) {
          final data = documentSnapshots[index].data() as Map?;
          return ListTile(
            leading: CircleAvatar(child: Icon(Icons.person)),
            title: data == null ? Text('Error in data') : Text(data['name']),
            subtitle: Text(documentSnapshots[index].id),
          );
        },
        // orderBy is compulsory to enable pagination
        query: FirebaseFirestore.instance.collection('users').orderBy('name'),
        //Change types accordingly
        itemBuilderType: PaginateBuilderType.listView,
        // to fetch real-time data
        isLive: true,
      ),

To use with listeners:

      PaginateRefreshedChangeListener refreshChangeListener = PaginateRefreshedChangeListener();

      RefreshIndicator(
        child: PaginateFirestore(
          itemBuilder: (context, documentSnapshots, index) => ListTile(
            leading: CircleAvatar(child: Icon(Icons.person)),
            title: Text(documentSnapshots[index].data()['name']),
            subtitle: Text(documentSnapshots[index].id),
          ),
          // orderBy is compulsary to enable pagination
          query: Firestore.instance.collection('users').orderBy('name'),
          listeners: [
            refreshChangeListener,
          ],
        ),
        onRefresh: () async {
          refreshChangeListener.refreshed = true;
        },
      )

Contributions

Feel free to contribute to this project.

If you find a bug or want a feature, but don't know how to fix/implement it, please fill an issue. If you fixed a bug or implemented a feature, please send a pull request.

Getting Started

This project is a starting point for a Dart package, a library module containing code that can be shared easily across multiple Flutter or Dart projects.

For help getting started with Flutter, view our online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add paginate_firestore

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  paginate_firestore: ^1.0.3+1

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:paginate_firestore/paginate_firestore.dart'; 

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:paginate_firestore/paginate_firestore.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Firestore pagination library',
      theme: ThemeData(
        primarySwatch: Colors.yellow,
        visualDensity: VisualDensity.adaptivePlatformDensity,
        brightness: Brightness.dark,
      ),
      home: const HomePage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Firestore pagination example'),
        centerTitle: true,
      ),
      body: Scrollbar(
        isAlwaysShown: true,
        child: PaginateFirestore(
          // Use SliverAppBar in header to make it sticky
          header: const SliverToBoxAdapter(child: Text('HEADER')),
          footer: const SliverToBoxAdapter(child: Text('FOOTER')),
          // item builder type is compulsory.
          itemBuilderType:
              PaginateBuilderType.listView, //Change types accordingly
          itemBuilder: (context, documentSnapshots, index) {
            final data = documentSnapshots[index].data() as Map?;
            return ListTile(
              leading: const CircleAvatar(child: Icon(Icons.person)),
              title: data == null
                  ? const Text('Error in data')
                  : Text(data['name']),
              subtitle: Text(documentSnapshots[index].id),
            );
          },
          // orderBy is compulsory to enable pagination
          query: FirebaseFirestore.instance.collection('users').orderBy('name'),
          itemsPerPage: 5,
          // to fetch real-time data
          isLive: true,
        ),
      ),
    );
  }
} 

Download Details:

Author: vedartm

Source Code: https://github.com/vedartm/paginate_firestore

#flutter #android #ios #firestore 

A Flutter Package to Simplify Pagination with Firestore Data

Flamingo Is a Firebase Firestore Model Framework Library

flamingo_generator

Automatically generate code for converting flamingo JSON by annotating Dart classes.

import 'package:flamingo/flamingo.dart';
import 'package:flamingo_annotation/flamingo_annotation.dart';

import 'cart.dart';
import 'item.dart';

part 'user.flamingo.dart';

class User extends Document<User> {
  User({
    String id,
    DocumentSnapshot snapshot,
    Map<String, dynamic> values,
  }) : super(id: id, snapshot: snapshot, values: values) {
    item = Collection(this, UserFieldValueKey.item.value);
  }

  @Field()
  String name;

  @Field(isWriteNotNull: false)
  String profile;

  @Field()
  Map<String, int> intMap;

  @Field()
  List<Map<String, int>> listIntMap;

  @Field()
  Increment<int> point = Increment('point');

  @Field()
  Increment<double> score = Increment('score');

  @ModelField()
  Cart cartA;

  @ModelField(isWriteNotNull: false)
  Cart cartB;

  @ModelField()
  List<Cart> carts;

  @StorageField()
  StorageFile fileA;

  @StorageField(isWriteNotNull: false, folderName: 'image')
  StorageFile fileB;

  @StorageField()
  List<StorageFile> filesA;

  @StorageField(isWriteNotNull: false)
  List<StorageFile> filesB;

  @SubCollection()
  Collection<Item> item;

  @override
  Map<String, dynamic> toData() => _$toData(this);

  @override
  void fromData(Map<String, dynamic> data) => _$fromData(this, data);
}

Generate the following code.

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'user.dart';

// **************************************************************************
// FieldValueGenerator
// **************************************************************************

/// FieldValueKey
enum UserFieldValueKey {
  name,
  profile,
  intMap,
  listIntMap,
  point,
  score,
  cartA,
  cartB,
  carts,
  fileA,
  fileB,
  filesA,
  filesB,
  item,
}

extension UserFieldValueKeyExtension on UserFieldValueKey {
  String get value {
    switch (this) {
      case UserFieldValueKey.name:
        return 'name';
      case UserFieldValueKey.profile:
        return 'profile';
      case UserFieldValueKey.intMap:
        return 'intMap';
      case UserFieldValueKey.listIntMap:
        return 'listIntMap';
      case UserFieldValueKey.point:
        return 'point';
      case UserFieldValueKey.score:
        return 'score';
      case UserFieldValueKey.cartA:
        return 'cartA';
      case UserFieldValueKey.cartB:
        return 'cartB';
      case UserFieldValueKey.carts:
        return 'carts';
      case UserFieldValueKey.fileA:
        return 'fileA';
      case UserFieldValueKey.fileB:
        return 'fileB';
      case UserFieldValueKey.filesA:
        return 'filesA';
      case UserFieldValueKey.filesB:
        return 'filesB';
      case UserFieldValueKey.item:
        return 'item';
      default:
        return toString();
    }
  }
}

/// For save data
Map<String, dynamic> _$toData(User doc) {
  final data = <String, dynamic>{};
  Helper.writeNotNull(data, 'name', doc.name);
  Helper.write(data, 'profile', doc.profile);
  Helper.writeNotNull(data, 'intMap', doc.intMap);
  Helper.writeNotNull(data, 'listIntMap', doc.listIntMap);
  Helper.writeIncrement(data, doc.point);
  Helper.writeIncrement(data, doc.score);

  Helper.writeModelNotNull(data, 'cartA', doc.cartA);
  Helper.writeModel(data, 'cartB', doc.cartB);
  Helper.writeModelListNotNull(data, 'carts', doc.carts);

  Helper.writeStorageNotNull(data, 'fileA', doc.fileA, isSetNull: false);
  Helper.writeStorage(data, 'image', doc.fileB, isSetNull: false);
  Helper.writeStorageListNotNull(data, 'filesA', doc.filesA, isSetNull: false);
  Helper.writeStorageList(data, 'filesB', doc.filesB, isSetNull: false);

  return data;
}

/// For load data
void _$fromData(User doc, Map<String, dynamic> data) {
  doc.name = Helper.valueFromKey<String>(data, 'name');
  doc.profile = Helper.valueFromKey<String>(data, 'profile');
  doc.intMap = Helper.valueMapFromKey<String, int>(data, 'intMap');
  doc.listIntMap = Helper.valueMapListFromKey<String, int>(data, 'listIntMap');
  doc.point = Helper.valueFromIncrement<int>(data, doc.point.fieldName);
  doc.score = Helper.valueFromIncrement<double>(data, doc.score.fieldName);

  final _cartA = Helper.valueMapFromKey<String, dynamic>(data, 'cartA');
  if (_cartA != null) {
    doc.cartA = Cart(values: _cartA);
  } else {
    doc.cartA = null;
  }

  final _cartB = Helper.valueMapFromKey<String, dynamic>(data, 'cartB');
  if (_cartB != null) {
    doc.cartB = Cart(values: _cartB);
  } else {
    doc.cartB = null;
  }

  final _carts = Helper.valueMapListFromKey<String, dynamic>(data, 'carts');
  if (_carts != null) {
    doc.carts =
        _carts.where((d) => d != null).map((d) => Cart(values: d)).toList();
  } else {
    doc.carts = null;
  }

  doc.fileA = Helper.storageFile(data, 'fileA');
  doc.fileB = Helper.storageFile(data, 'image');
  doc.filesA = Helper.storageFiles(data, 'filesA');
  doc.filesB = Helper.storageFiles(data, 'filesB');
}

Use this package as a library

Depend on it

Run this command:

With Dart:

 $ dart pub add flamingo_generator

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):

dependencies:
  flamingo_generator: ^0.13.0

Alternatively, your editor might support dart pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:flamingo_generator/flamingo_generator.dart'; 

example/README.md

flamingo_generator_example

Demonstrates how to use the flamingo_generator plugin.

Getting Started

This project is a starting point for a Flutter application.

A few resources to get you started if this is your first Flutter project:

For help getting started with Flutter, view our online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference. 

Download Details:

Author: hukusuke1007

Source Code: https://github.com/hukusuke1007/flamingo

#flutter #firestore 

Flamingo Is a Firebase Firestore Model Framework Library

A Flutter Plugin for Fetching Firestore Documents

Firestore Cache

A Flutter plugin for fetching Firestore documents with read from cache first then server.

This plugin is mainly designed for applications using the DocumentReference.get() and Query.get() methods in the cloud_firestore plugin, and is implemented with read from cache first then server.

Getting Started

Add this to your package's pubspec.yaml file:

dependencies:
  firestore_cache: ^2.2.1

Usage

Before using the plugin, you will need to create a document on Firestore and create a timestamp field in that document. See the screenshot below for an example:

Firestore Screenshot

⚠️ PLEASE NOTE This plugin does not compare the documents in the cache and the ones in the server to determine if it should fetch data from the server. Instead, it relies on the timestamp field in the document to make that decision. And so your application should implement the logic to update this field if you want to read new data from the server instead of reading it from the cache.

You should also create different timestamp fields for different collections or documents that you are fetching.

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

// This should be the path of the document containing the timestampe field
// that you created
final cacheDocRef = Firestore.instance.doc('status/status');

// This should be the timestamp field in that document
final cacheField = 'updatedAt';

final query = Firestore.instance.collection('posts');
final snapshot = await FirestoreCache.getDocuments(
    query: query,
    cacheDocRef: cacheDocRef,
    firestoreCacheField: cacheField,
);

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add firestore_cache

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  firestore_cache: ^2.2.1

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:firestore_cache/firestore_cache.dart'; 

example/lib/main.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firestore_cache/firestore_cache.dart';
import 'package:flutter/material.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(const MyApp());
}

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Firestore Cache Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {
  final _firestore = FirebaseFirestore.instance;
  late Future<DocumentSnapshot<Map<String, dynamic>>> _futureDoc;
  late Future<QuerySnapshot<Map<String, dynamic>>> _futureSnapshot;

  @override
  void initState() {
    super.initState();
    _futureDoc = _getDoc();
    _futureSnapshot = _getDocs();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Firestore Cache Demo')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            _buildDoc(),
            _buildDocs(),
          ],
        ),
      ),
    );
  }

  Widget _buildDoc() {
    return FutureBuilder<DocumentSnapshot>(
      future: _futureDoc,
      builder: (context, snapshot) {
        if (snapshot.hasError) {
          return Text('${snapshot.error}');
        } else if (snapshot.hasData) {
          final doc = snapshot.data!;
          final data = doc.data() as Map?;

          return Text(
            '${data!['userId']} isFromCache: ${doc.metadata.isFromCache}',
          );
        }

        return const CircularProgressIndicator();
      },
    );
  }

  Widget _buildDocs() {
    return FutureBuilder<QuerySnapshot>(
      future: _futureSnapshot,
      builder: (context, snapshot) {
        if (snapshot.hasError) {
          return Text('${snapshot.error}');
        } else if (snapshot.hasData) {
          final docs = snapshot.data?.docs;
          return Expanded(
            child: ListView(
              children: docs!.map((DocumentSnapshot doc) {
                final data = doc.data() as Map?;
                return Text(
                  '${data!['postId']} isFromCache: ${doc.metadata.isFromCache}',
                  textAlign: TextAlign.center,
                );
              }).toList(),
            ),
          );
        }

        return const CircularProgressIndicator();
      },
    );
  }

  Future<DocumentSnapshot<Map<String, dynamic>>> _getDoc() async {
    final docRef = _firestore.doc('users/user');
    final doc = await FirestoreCache.getDocument(docRef);

    return doc;
  }

  Future<QuerySnapshot<Map<String, dynamic>>> _getDocs() async {
    const cacheField = 'updatedAt';
    final cacheDocRef = _firestore.doc('status/status');
    final query = _firestore.collection('posts');
    final snapshot = await FirestoreCache.getDocuments(
      query: query,
      cacheDocRef: cacheDocRef,
      firestoreCacheField: cacheField,
    );

    return snapshot;
  }
} 

Download Details:

Author: zeshuaro

Source Code: https://github.com/zeshuaro/firestore_cache

#flutter #firestore #cache 

A Flutter Plugin for Fetching Firestore Documents
Effie  Predovic

Effie Predovic

1653910920

Build and Deploy Responsive Blog in React using Firestore

Hi Everyone, in this video we will build responsive using Sass in React with the help of Firestore. In this blog, app we will having full email authentication along with CRUD feature, after we will deploy our project on Firebase.

Git-hub repo :- https://github.com/trickjsprogram/firebase-blog

#firestore #react 

Build and Deploy Responsive Blog in React using Firestore
Bulah  Pfeffer

Bulah Pfeffer

1650857301

How to Build a Full Stack Application with Flutter and Firebase

Flutter Firebase Tutorial | Redux & Firestore

Flutter is google ui toolkit for building natively compiled apps with one single codebase for different platforms. Firebase serves as a back end service. This video teaches you to use both to build a fullstack application. This is a brand new course and also a good help to beginners. We used Flutter, Firebae, firestore for collection storing.

0:00 - Intro
0:23 - Slides on Flutter & Firebase
3:22 - Project Preview
4:04 - Tutorial Starts

Source Code: https://github.com/boltdsg/Flutter-User-Authentication-vs-Firebase 

#flutter #firebase #redux #firestore

How to Build a Full Stack Application with Flutter and Firebase
React Native

React Native

1650672000

React Native and Firebase: Authentication Database and Firestore

sample-react-native-firebase

A sample app built with React Native, TypeScript and Firebase Resources: Authentication and Firestore Database

A sample app built with React Native, TypeScript and Firebase Resources: Authentication and Firestore Database.

A sample app built with React Native, TypeScript and Firebase Resources: Authentication and Firestore Database

The android/app/google-services.json has its values ​​omitted for the security of my Firebase account.

Running Locally

Before the steps below, create a Firebase project, download the google-services.json file and replace my project’s android/app/google-services.json with the file you downloaded.

Then, connect your cell phone to your computer or open an Android emulator.

#If you choose to run the app on your mobile, make sure it connected correctly
adb devices -l

#Install dependencies
yarn install

# start the metro server
react-native start

Leave the metro server in a separate tab and open a new tab.

react-native run-android

Author: victorts1991
Source Code: https://github.com/victorts1991/sample-react-native-firebase
License: 
#react-native #firestore #firebase #typescript 

React Native and Firebase: Authentication Database and Firestore
Grace  Edwards

Grace Edwards

1649845800

How to Perform CRUD Operation Firebase 9 & React

In this video tutorial, We'll show you How to Perform CRUD Operation Firebase React | Firebase 9 and Firestore Tutorial Hindi. Very simple and effective that not everyone knows (40 Mins)

Starter Project Link - https://github.com/anshuopinion/firebase-crud-typescript/tree/starter

#firebase #react #firestore #crud 

How to Perform CRUD Operation Firebase 9 & React

Building a Realtime App with Firebase and Ember M3

Building a Realtime App with Firebase and Ember M3

Ember Data is a powerful data layer, but it has its limitations and pain points, especially as applications grow in scale. Ember M3 builds on Ember Data's core, but replaces the default model class with an alternative that is more flexible and lightweight. In this talk, we'll explore M3's capabilities, and then test them out by building an app with M3 and Firestore, a realtime NoSQL database-as-a-service. As we'll see, M3 and Firestore make a perfect pair, enabling rapid prototyping and flexibility, while setting you up for success as your application grows.

#firebase #ember #database #nosql #firestore

Building a Realtime App with Firebase and Ember M3

Google Cloud Firestore Y Base De Datos En Tiempo Real En Flutter

Google ofrece servicios para mantener la persistencia de los datos en el tiempo. Los datos utilizados por nuestras aplicaciones deben estar disponibles cuando los necesitemos, de fácil acceso y preferiblemente estructurados para que estén listos para ser utilizados por nuestra aplicación.

Cloud Firestore y Firebase Realtime Database son dos servicios proporcionados por Google. Ambos pueden hacer lo que requiere nuestra aplicación, pero tienen una variedad de diferencias entre ellos; esto en realidad los convierte en los más adecuados para tipos de aplicaciones específicos.

Este artículo le mostrará qué base de datos es preferible para las consultas de la aplicación Flutter. Para comenzar, proporcionaremos un desglose rápido de lo que cubre este artículo, nuestro caso de uso de ejemplo, los requisitos previos y nuestros procesos.

lo que cubriremos

En este artículo, lo guiaremos a través de lo siguiente:

  • Cómo conectar una aplicación Flutter a Cloud Firestore y una base de datos en tiempo real por separado
  • Cómo se diferencian en términos de consultas de datos

nuestro ejemplo

Crearemos una aplicación que permita a los usuarios registrados en la plataforma emitir votos sobre un tema en particular o una decisión a tomar.

El conjunto de datos de muestra que se usará nos permitirá mostrar la diferencia entre Cloud Firestore y Realtime Database por dos razones:

  • Su conectividad con nuestra aplicación Flutter
  • Cómo difieren en las funcionalidades de consulta que pueden manejar

requisitos previos

  • Conocimiento de cómo crear aplicaciones básicas de Flutter.
  • Familiaridad con el concepto de NoSql/almacenamiento de datos basado en documentos
  • Conocer Cloud Firestore o Realtime Database, ya sea fuera de Flutter o con Flutter, es una ventaja.

Ejecutar a través de

Nuestro flujo tomará la siguiente estructura:

  • Ejecutaremos una configuración de back-end de base de datos simple para nuestra aplicación. Este paso se aplica tanto a Cloud Firestore como a Realtime Database. (Nota: Destacaremos la diferencia entre ambos procesos a medida que avancemos)
  • Configuraremos nuestra aplicación Flutter con un código básico. Hacemos esto para respaldar el núcleo de nuestro punto de aplicación, que es cuando los usuarios emiten sus votos; por lo tanto, ambas bases de datos se completarán previamente con datos que podemos usar. Estos datos se insertarán en nuestra base de datos desde nuestra aplicación y no mediante ningún proceso manual ad hoc, como en nuestro caso.
  • Mostraremos la distinción entre ellos al conectar y realizar operaciones simples de lectura y escritura.
  • Luego mostraremos cómo difieren en función de sus distintas capacidades de consulta.

Tienda de fuego en la nube

Cloud Firestore es una base de datos de documentos NoSQL que simplifica el almacenamiento, la sincronización y la consulta de datos para aplicaciones a escala global.

Es una excelente manera de poner el backend en una aplicación Flutter sin la molestia de tener un servidor. Cloud Firestore permite estructuras de consulta complejas en comparación con las bases de datos en tiempo real. Debido a que nuestros datos están estructurados cuando se almacenan (como documentos), podemos realizar consultas más engorrosas o imposibles en comparación con Realtime Database.

Para nuestro ejemplo, necesitaremos una fuente de back-end que comparta datos entre todas las aplicaciones y pueda rastrear la persistencia de los votos emitidos por diferentes miembros en diferentes ubicaciones.

Con Cloud Firestore, podemos crear colecciones para los usuarios que pueden participar en una sesión de votación y agrupar la lista de posibles decisiones para las que pueden emitir votos. Cuando hagamos nuestras colecciones, integraremos Cloud Firestore en nuestra aplicación y construiremos nuestros widgets de Flutter usando datos de esa colección. Firestore maneja la mayoría de los detalles más pequeños, asegurando actualizaciones de información persistentes y la transmisión de cambios a todas las instancias de aplicaciones existentes.

Creando nuestra aplicación Flutter

Anímate a crear una nueva aplicación de Flutter para realizar nuestras operaciones con Firestore.

Creando nuestro proyecto Firebase

Para comenzar, crearemos un proyecto de Flutter.

Primero, necesitamos configurar un proyecto de Firebase para nuestra aplicación. Para hacer esto, dirígete a Firebase y crea un nuevo proyecto.

Usaremos el nombre de nuestra aplicación, votersapp. A continuación, haga clic en "Continuar" para crear un proyecto. (Nota: Habilitar Google Analytics es una elección personal).

Después de crear el proyecto, haga clic en "Continuar" y registre las aplicaciones individuales para el proyecto. Registraremos nuestro proyecto para un dispositivo Android haciendo clic en el ícono de Android en nuestra página actual. El proceso es prácticamente el mismo si registramos una aplicación de iOS o registramos ambas plataformas.

Vaya a nuestra aplicación Flutter para el campo de nombre del paquete de Android; copie el nombre de la empresa (nombre de dominio inverso) e ingréselo. Esto se puede encontrar en el archivo androidmanifest.xml.

Una vez completado, haga clic para descargar el archivo de configuración y luego haga clic en "Siguiente".

Ahora, tendremos que establecer algunas configuraciones básicas para asegurarnos de que Firebase pueda completar el registro de nuestra aplicación y comunicarse con ella.

Arrastre el archivo google-services.json que descargamos anteriormente e insértelo en nuestro directorio android/app/.

Configura el complemento Firebase Gradle. Abra el archivo build.gradle en nuestro directorio de Android del proyecto Flutter y agregue este código a las siguientes dependencias a continuación:

classpath 'com.google.gms:google-services:4.3.10
{
classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}

A continuación, abra el archivo android/app/build.gradle y agregue lo siguiente a la apply pluginclave: 'com.google.gms.google-services'.

A continuación, diríjase a https://pub.dev/packages/cloud_firestore , obtenga la última versión de Cloud Firestore y agréguela a nuestro archivo pubspec.YAML.

Ejecute Flutter pub getpara obtener el complemento.

A continuación, seleccione Cloud Firestore en el panel de nuestra consola. En la base de datos build/firestore, seleccione "modo de prueba" y actívelo.

A continuación, crearemos una colección llamada "Usuarios". La colección tendrá un documento de cada usuario que pueda votar. Luego lo llenaremos con cuatro usuarios; “Ade”, “Bisi”, “David” y “Claire”.

Con esto, tenemos nuestro backend todo configurado. Ahora, necesitaremos que nuestra aplicación se comunique con nuestro backend de Firebase. Usaremos el complemento Cloud Firestore en nuestra aplicación Flutter.

Nuestra aplicación Flutter

Para nuestra aplicación Flutter, mostraré una captura de pantalla para demostrar la idea central de este tutorial.

Lectura de nuestra Cloud Firestore

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();

 await Firebase.initializeApp();
 runApp(const MyApp());
}

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

 // This widget is the root of your application.
 @override
 Widget build(BuildContext context) {
 return MaterialApp(
 title: 'Flutter Demo',
 theme: ThemeData(
 primarySwatch: Colors.blue,
 ),
 home: const MyHomePage(title: 'Flutter Demo Home Page'),
 );
 }
}

class MyHomePage extends StatefulWidget {
 const MyHomePage({Key? key, required this.title}) : super(key: key);

 final String title;

 @override
 State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
 final Stream<QuerySnapshot> _usersStream =
 FirebaseFirestore.instance.collection('users').snapshots();

 @override
Widget build(BuildContext context) {
 return Scaffold(
 appBar: AppBar(
 title: Text(widget.title),
 ),
 body: SingleChildScrollView(
 child: Container(
 margin: EdgeInsets.symmetric(
  vertical: MediaQuery.of(context).size.height * 0.04,
  horizontal: MediaQuery.of(context).size.width * 0.04),
 child: Column(
  mainAxisAlignment: MainAxisAlignment.start,
  crossAxisAlignment: CrossAxisAlignment.start,
  children: <Widget>[
  const Text(
   'Enter user name',
  style: TextStyle(fontSize: 16),
  ),
  const SizedBox(
  height: 10,
  ),
  TextField(

  onChanged: (value) {
  //Do something with the user input.

  },
  decoration: const InputDecoration(
  hintText: 'Enter your password.',
  contentPadding:
   EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
  border: OutlineInputBorder(
   borderRadius: BorderRadius.all(Radius.circular(6.0)),
  ),
  ),
  ),

  , icon: Icon(Icons.add), label: Text('Add user')),
  const SizedBox(
  height: 20,
  ),
  StreamBuilder<QuerySnapshot>(
  stream: _usersStream,
  builder: (BuildContext context,
   AsyncSnapshot<QuerySnapshot> snapshot) {
   if (snapshot.hasError) {
   return const Text('Something went wrong');
   }
   if (snapshot.connectionState == ConnectionState.waiting) {
   return const Text("Loading");
   }
   return ListView(
   shrinkWrap: true,
   children:
   snapshot.data!.docs.map((DocumentSnapshot document) {
   Map<String, dynamic> data =
    document.data()! as Map<String, dynamic>;
   return ListTile(
   title: Text(data['name']),
   );
   }).toList(),
   );
  })
  ],
 ),
 ),
 ),
 );
}
}

Explicación del fragmento de código

En el código anterior, importamos los complementos necesarios para nuestra aplicación Flutter.

(Nota: Firestore requiere un núcleo de Firebase, por lo que lo agregamos a nuestro archivo pubspec.YAML y también lo importamos a nuestra aplicación).

El siguiente código inicializa Firebase en nuestra aplicación. Como nota adicional, cuando construimos nuestro widget, tenemos un campo de texto y una lista de nuestros usuarios actuales en nuestra base de datos. Envolvimos nuestro widget con SingleChildScrollViewy configuramos nuestra ListView ShrinkWrappropiedad truepara evitar la superposición.

WidgetsFlutterBinding.ensureInitialized();

await Firebase.initializeApp();

El siguiente código es la potencia principal: realiza la función de lectura de nuestro Cloud Firestore.

final Stream<QuerySnapshot> _usersStream =
 FirebaseFirestore.instance.collection('users').snapshots();

Obtiene una instancia de nuestra colección de usuarios y la almacena en nuestra Stream<QuerySnapshot>variable.

El siguiente código es un widget de Flutter: esto crea una secuencia que actualiza el estado del widget cada vez que hay un cambio en la instantánea de datos en la base de datos. Muestra una lista de todos los usuarios.

StreamBuilder<QuerySnapshot>(
  stream: _usersStream,
  builder: (BuildContext context,
   AsyncSnapshot<QuerySnapshot> snapshot) {
   if (snapshot.hasError) {
   return const Text('Something went wrong');
   }
   if (snapshot.connectionState == ConnectionState.waiting) {
   return const Text("Loading");
   }
   return ListView(
   shrinkWrap: true,
   children:
   snapshot.data!.docs.map((DocumentSnapshot document) {
   Map<String, dynamic> data =
    document.data()! as Map<String, dynamic>;
   return ListTile(
   title: Text(data['name']),
   );
   }).toList(),
   );
  })
  )

Operación de escritura de Firestore

Para realizar una operación de escritura, primero crearemos una instancia de colección y una variable para contener la entrada de texto de nuestro usuario. Aquí se muestra un ejemplo:

CollectionReference users = FirebaseFirestore.instance.collection('users');
String name = '';

A continuación, crearemos una función que inserte un documento en nuestra base de datos utilizando Cloud Firestore.

Future<void> addUser() {
 // Call the user's CollectionReference to add a new user
 return users
  .add({
  'name': name, // John Doe
 })
  .then((value) => print("User Added"))
  .catchError((error) => print("Failed to add user: $error"));
}

Agregamos un widget de botón en nuestro código y configuramos la onPressedfunción para actualizar la variable de nombre con el contenido del campo de texto. Nuestro código base se convierte en esto:

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

Future<void> main() async {
 WidgetsFlutterBinding.ensureInitialized();
 await Firebase.initializeApp();
 runApp(const MyApp());
}

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

 // This widget is the root of your application.
 @override
 Widget build(BuildContext context) {
 return MaterialApp(
  title: 'Flutter Demo',
  theme: ThemeData(
  primarySwatch: Colors.blue,
  ),
  home: const MyHomePage(title: 'Flutter Demo Home Page'),
 );
 }
}

class MyHomePage extends StatefulWidget {
 const MyHomePage({Key? key, required this.title}) : super(key: key);

 final String title;

 @override
 State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
 final Stream<QuerySnapshot> _usersStream =
  FirebaseFirestore.instance.collection('users').snapshots();

 CollectionReference users = FirebaseFirestore.instance.collection('users');

 String name = '';

 Future<void> addUser() {
 // Call the user's CollectionReference to add a new user
 return users
  .add({
  'name': name, // John Doe
 })
  .then((value) => print("User Added"))
  .catchError((error) => print("Failed to add user: $error"));
 }

 @override
 Widget build(BuildContext context) {
 return Scaffold(
  appBar: AppBar(
  title: Text(widget.title),
  ),
  body: SingleChildScrollView(
  child: Container(
   margin: EdgeInsets.symmetric(
    vertical: MediaQuery.of(context).size.height * 0.04,
    horizontal: MediaQuery.of(context).size.width * 0.04),
   child: Column(
   mainAxisAlignment: MainAxisAlignment.start,
   crossAxisAlignment: CrossAxisAlignment.start,
   children: <Widget>[
    const Text(
     'Enter user name',
    style: TextStyle(fontSize: 16),
    ),
    const SizedBox(
    height: 10,
    ),
    TextField(
    onChanged: (value) {
     //Do something with the user input.
     name = value;
    },
    decoration: const InputDecoration(
     hintText: 'Enter your password.',
     contentPadding:
      EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
     border: OutlineInputBorder(
     borderRadius: BorderRadius.all(Radius.circular(6.0)),
     ),
    ),
    ),
    const SizedBox(
    height: 5,
    ),
    ElevatedButton.icon(
     onPressed: (){
     addUser();
    }, icon: Icon(Icons.add), label: Text('Add user')),
    const SizedBox(
    height: 20,
    ),
    StreamBuilder<QuerySnapshot>(
     stream: _usersStream,
     builder: (BuildContext context,
      AsyncSnapshot<QuerySnapshot> snapshot) {
     if (snapshot.hasError) {
      return const Text('Something went wrong');
     }
     if (snapshot.connectionState == ConnectionState.waiting) {
      return const Text("Loading");
     }
     return ListView(
      shrinkWrap: true,
      children:
       snapshot.data!.docs.map((DocumentSnapshot document) {
      Map<String, dynamic> data =
       document.data()! as Map<String, dynamic>;
      return ListTile(
       title: Text(data['name']),
      );
      }).toList(),
     );
     })
   ],
   ),
  ),
  ),
 );
 }
}

Aquí se enumeran otras funciones de Cloud Firestore:
https://firebase.flutter.dev/docs/firestore/usage/ .

(Nota: en Cloud Firestore, podemos encadenar filtros y combinar filtrado y clasificación en una propiedad en una sola consulta).

Base de datos en tiempo real

La configuración de nuestro proyecto de backend de Firebase es similar a lo que hemos hecho con Cloud Firestore, solo que, al seleccionar nuestra base de datos, seleccionamos la base de datos en tiempo real y no la base de datos de Firestore.

Nuestra aplicación Flutter

Usaremos un complemento diferente para esta sección en comparación con Cloud Firestore. Por lo tanto, en nuestro pubspec.YAMLarchivo, agregamos Firebase_database como dependencia. Para nuestra aplicación Flutter, debemos seguir los pasos a continuación.

Primero, importamos Firebase_database a nuestro archivo Dart.

import 'package:firebase_database/firebase_database.dart';

A continuación, para inicializar nuestra aplicación, usamos el siguiente código:

WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();

Cabe señalar que Realtime Database almacena datos como JSON, lo que nos permite acceder a los nodos de los datos a través de un archivo DatabaseReference. Por ejemplo, si almacenamos nuestros datos como se muestra a continuación, podemos crear referencias para cada búsqueda. Es decir:

{
 "users":
   “One”: {
  "name": "Ade"
 },
   “Two”: {
  "name": "Bisi"
 },
   ‘Three”: {
  "name": "David"
 },
   ‘Four”: {
  "name": "Claire"
 }
}

Podemos crear una referencia a un nodo proporcionando una ruta:

  • usuarios/: crea una referencia a todo el objeto "usuarios"
  • usuarios/Uno: crea una referencia al objeto de usuario "Uno"
  • usuarios/Dos/nombre: Crea una referencia a la propiedad (con el valor de “Bisi”)
DatabaseReference ref = FirebaseDatabase.instance.ref("voters/1/users/1");

(Nota: si no proporciona una ruta, la referencia apuntará a la raíz de su base de datos).

Adición de datos a la base de datos en tiempo real

Para esta sección, escribiremos datos en nuestra base de datos agregando un nuevo usuario tal como lo hicimos en Firestore. Para ello, tenemos que seguir estos pasos.

Primero, crea una referencia a la ruta en la que queremos escribir.

final refDataInstance = FirebaseDatabase.instance.reference().child('users');

A continuación, tenemos nuestro código completo que lee datos de nuestra base de datos en tiempo real y escribe nuevos usuarios en nuestra base de datos.

import 'package:firebase_database/ui/firebase_animated_list.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';

Future<void> main() async {
 WidgetsFlutterBinding.ensureInitialized();

 var app = await Firebase.initializeApp();
 runApp(MaterialApp(
  title: 'Flutter Demo',
  theme: ThemeData(
  primarySwatch: Colors.blue,
  ),
  home: MyHomePage(app: app, title: 'Flutter Demo')));
}

class MyHomePage extends StatefulWidget {
 final FirebaseApp app;

 const MyHomePage({Key? key, required this.title, required this.app})
  : super(key: key);

 final String title;

 @override
 State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
 final refDataInstance = FirebaseDatabase.instance.reference().child('users');

 String name = '';

 @override
 Widget build(BuildContext context) {
 return Scaffold(
  appBar: AppBar(
  title: Text(widget.title),
  ),
  body: SingleChildScrollView(
  child: Container(
   height: MediaQuery.of(context).size.height,
   margin: EdgeInsets.symmetric(
    vertical: MediaQuery.of(context).size.height * 0.04,
    horizontal: MediaQuery.of(context).size.width * 0.04),
   child: Column(
   mainAxisAlignment: MainAxisAlignment.start,
   crossAxisAlignment: CrossAxisAlignment.start,
   children: <Widget>[
    const Text(
    'Enter user name',
    style: TextStyle(fontSize: 16),
    ),
    const SizedBox(
    height: 10,
    ),
    TextField(
    onChanged: (value) {
     //Do something with the user input.
     name = value;
    },
    decoration: const InputDecoration(
     hintText: 'Enter your password.',
     contentPadding:
      EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
     border: OutlineInputBorder(
     borderRadius: BorderRadius.all(Radius.circular(6.0)),
     ),
    ),
    ),
    const SizedBox(
    height: 5,
    ),
    ElevatedButton.icon(
     onPressed: () {
     // adds new user to DB
     refDataInstance.push().child('name').set(name).asStream();
     },
     icon: const Icon(Icons.add),
     label: const Text('Add user')),
    const SizedBox(
    height: 20,
    ),
    Flexible(
     child: FirebaseAnimatedList(
    shrinkWrap: true,
    query: refDataInstance,
    itemBuilder: (BuildContext context, DataSnapshot snapshot,
     Animation<double> animation, int index) {
     return ListTile(
     title: Text(snapshot.value['users']),
     );
    },
    )),
   ],
   ),
  ),
  ),
 );
 }
}

Escribir en nuestra base de datos en tiempo real

Hacemos uso de la siguiente expresión para realizar nuestra operación de escritura. Usando la instancia de referencia de nuestra base de datos, podemos escribir el valor de nuestra variable de nombre en la onTapfunción de nuestro elevatedButtonwidget.

refDataInstance.push().child('name').set(name).asStream();

Lectura de nuestra instancia de base de datos

Usando el FirebaseAnimatedListwidget de Firebase, podemos realizar una escritura o lectura de transmisión en vivo cada vez que cambiamos nuestra base de datos.

FirebaseAnimatedList(
 shrinkWrap: true,
 query: refDataInstance,
 itemBuilder: (BuildContext context, DataSnapshot snapshot,
  Animation<double> animation, int index) {
 return ListTile(
  title: Text(snapshot.value['users']),
 );
 },
)

(Nota: en una base de datos en tiempo real, podemos filtrar u ordenar datos en una sola consulta en una sola propiedad, no en varias).

Conclusión

Cloud Firestore permite estructuras de consulta complejas en comparación con las bases de datos en tiempo real. Debido a que nuestros datos están estructurados cuando se almacenan (como documentos), podemos realizar consultas engorrosas en Cloud Firerstore.

Podemos optar por filtrar u ordenar los datos en una sola consulta en una sola propiedad, en comparación con solo varias propiedades como en la base de datos en tiempo real. En Cloud Firestore, podemos encadenar filtros y combinar filtrado y clasificación en una propiedad en una sola consulta.

Si queremos obtener datos en orden descendente, Cloud Firestore es muy útil donde Realtime Database no ofrece una función de consulta, y también podemos encadenar múltiples métodos "dónde" para crear consultas más específicas (AND lógico) en Cloud Firestore.

users.whereEqualTo("name", "Bisi").whereEqualTo("vote", 0);

Por estas razones, recomendaría fuertemente a Cloud Firestore cuando busque una base de datos con la mejor capacidad de consulta para una aplicación de Flutter. Hemos visto cómo Cloud Firestore supera a su homólogo de Firebase con los pocos ejemplos anteriores.

Codificación feliz 💻

Enlace: https://blog.logrocket.com/google-cloud-firestore-realtime-database-flutter/

#flutter  #google   #firestore 

Google Cloud Firestore Y Base De Datos En Tiempo Real En Flutter

FlutterのGoogleCloudFirestoreとRealtimeDatabase

Googleは、データの永続性を長期にわたって維持するためのサービスを提供しています。アプリケーションで使用されるデータは、必要なときに利用可能で、簡単にアクセスでき、できればアプリですぐに使用できるように構成されている必要があります。

CloudFirestoreとFirebaseRealtimeDatabaseは、Googleが提供する2つのサービスです。どちらもアプリケーションに必要なことを実行できますが、両者の間にはさまざまな違いがあります。これにより、実際には特定のアプリケーションタイプに最適になります。

この記事では、Flutterアプリケーションのクエリに適したデータベースを紹介します。はじめに、この記事の内容、使用例、前提条件、およびプロセスの概要を簡単に説明します。

カバーする内容

この記事では、以下について説明します。

  • FlutterアプリをCloudFirestoreとRealtimeDatabaseに別々に接続する方法
  • データクエリの観点からどのように差別化されているか

私たちの例

プラットフォームの登録ユーザーが特定のトピックや決定に投票できるアプリケーションを作成します。

使用するサンプルデータセットを使用すると、CloudFirestoreとRealtimeDatabaseの違いを次の2つの理由で紹介できます。

  • Flutterアプリケーションとの接続
  • 処理できるクエリ機能の違い

前提条件

  • 基本的なFlutterアプリケーションの作成方法に関する知識
  • NoSql/ドキュメントベースのデータストレージの概念に精通している
  • Flutterの外部にあるか、Flutterを使用しているかにかかわらず、CloudFirestoreまたはRealtimeDatabaseのいずれかを知っていることはプラスです

駆け抜ける

私たちのフローは次の構造を取ります:

  • アプリケーションの簡単なデータベースバックエンドのセットアップを実行します。この手順は、CloudFirestoreとRealtimeDatabaseの両方に適用されます。(注:進むにつれて、両方のプロセスの違いを強調します)
  • 基本的なコードを使用してFlutterアプリケーションをセットアップします。これは、ユーザーが投票するアプリケーションポイントのコアをサポートするために行います。したがって、両方のデータベースに、使用できるデータが事前に入力されます。このデータは、アプリケーションからデータベースに挿入されます。この場合のように、アドホックな手動プロセスを介しては挿入されません。
  • 単純な読み取りおよび書き込み操作を接続して実行する際のそれらの違いを示します
  • 次に、個別のクエリ機能に基づいてそれらがどのように異なるかを示します

CloudFirestore

Cloud FirestoreはNoSQLドキュメントデータベースであり、アプリのデータの保存、同期、クエリをグローバル規模で簡素化します。

これは、サーバーを用意する手間をかけずに、バックエンドをFlutterアプリに配置するための優れた方法です。Cloud Firestoreは、リアルタイムデータベースと比較すると、複雑なクエリ構造を可能にします。データは(ドキュメントとして)保存されるときに構造化されるため、リアルタイムデータベースと比較して、より面倒または不可能なクエリを実行できます。

この例では、すべてのアプリ間でデータを共有し、さまざまな場所でさまざまなメンバーが投じた投票の持続性を追跡できるバックエンドソースが必要になります。

Cloud Firestoreを使用すると、投票セッションに参加できるユーザー向けのコレクションを作成し、投票できる可能性のある決定のリストをグループ化できます。コレクションを作成するときは、Cloud Firestoreをアプリケーションに統合し、そのコレクションのデータを使用してFlutterウィジェットを構築します。Firestoreは細部のほとんどを処理し、永続的な情報の更新と既存のすべてのアプリインスタンスへの変更の中継を保証します。

Flutterアプリケーションの作成

先に進み、Firestoreで操作を実行するための新しいFlutterアプリケーションを作成します。

Firebaseプロジェクトの作成

まず、Flutterプロジェクトを作成します。

まず、アプリケーション用にFirebaseプロジェクトを設定する必要があります。これを行うには、Firebaseにアクセスして新しいプロジェクトを作成します。

アプリ名を使用しますvotersapp。次に、「続行」をクリックしてプロジェクトを作成します。(注:Google Analyticsを有効にすることは個人的な選択です)。

プロジェクトを作成したら、「続行」をクリックして、プロジェクトの個々のアプリを登録します。現在のページのAndroidアイコンをクリックして、プロジェクトをAndroidデバイスに登録します。iOSアプリケーションを登録する場合、または両方のプラットフォームを登録する場合、プロセスはほぼ同じです。

Androidパッケージ名フィールドのFlutterアプリケーションに移動します。会社名(逆ドメイン名)をコピーして入力します。これはandroidmanifest.xmlファイルにあります。

完了したら、をクリックして構成ファイルをダウンロードし、[次へ]をクリックします。

次に、Firebaseがアプリケーションの登録を完了して通信できるように、いくつかの基本的な構成を設定する必要があります。

以前にダウンロードしたgoogle-services.jsonファイルをドラッグして、android /app/ディレクトリに挿入します。

FirebaseGradleプラグインを設定します。FlutterプロジェクトのAndroidディレクトリにあるbuild.gradleファイルを開き、このコードを以下の依存関係に追加します。

classpath 'com.google.gms:google-services:4.3.10
{
classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}

次に、android / app / build.gradleファイルを開き、apply pluginキーに「com.google.gms.google-services」を追加します。

次に、https: //pub.dev/packages/cloud_firestoreにアクセスし、Cloud Firestoreの最新バージョンを取得して、pubspec.YAMLファイルに追加します。

Flutterpub getを実行してプラグインを取得します。

次に、コンソールダッシュボードからCloudFirestoreを選択します。ビルド/ファイアストアデータベースで、「テストモード」を選択して有効にします。

次に、「Users」というコレクションを作成します。コレクションには、投票できる各ユーザーのドキュメントが含まれます。次に、4人のユーザーを入力します。「Ade」、「Bisi」、「David」、「Claire」。

これで、バックエンドがすべてセットアップされました。次に、Firebaseバックエンドと通信するためのアプリケーションが必要になります。FlutterアプリケーションでCloudFirestoreプラグインを使用します。

Flutterアプリケーション

Flutterアプリケーションでは、このチュートリアルのコアアイデアを示すスクリーンショットを表示します。

CloudFirestoreからの読み取り

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();

 await Firebase.initializeApp();
 runApp(const MyApp());
}

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

 // This widget is the root of your application.
 @override
 Widget build(BuildContext context) {
 return MaterialApp(
 title: 'Flutter Demo',
 theme: ThemeData(
 primarySwatch: Colors.blue,
 ),
 home: const MyHomePage(title: 'Flutter Demo Home Page'),
 );
 }
}

class MyHomePage extends StatefulWidget {
 const MyHomePage({Key? key, required this.title}) : super(key: key);

 final String title;

 @override
 State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
 final Stream<QuerySnapshot> _usersStream =
 FirebaseFirestore.instance.collection('users').snapshots();

 @override
Widget build(BuildContext context) {
 return Scaffold(
 appBar: AppBar(
 title: Text(widget.title),
 ),
 body: SingleChildScrollView(
 child: Container(
 margin: EdgeInsets.symmetric(
  vertical: MediaQuery.of(context).size.height * 0.04,
  horizontal: MediaQuery.of(context).size.width * 0.04),
 child: Column(
  mainAxisAlignment: MainAxisAlignment.start,
  crossAxisAlignment: CrossAxisAlignment.start,
  children: <Widget>[
  const Text(
   'Enter user name',
  style: TextStyle(fontSize: 16),
  ),
  const SizedBox(
  height: 10,
  ),
  TextField(

  onChanged: (value) {
  //Do something with the user input.

  },
  decoration: const InputDecoration(
  hintText: 'Enter your password.',
  contentPadding:
   EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
  border: OutlineInputBorder(
   borderRadius: BorderRadius.all(Radius.circular(6.0)),
  ),
  ),
  ),

  , icon: Icon(Icons.add), label: Text('Add user')),
  const SizedBox(
  height: 20,
  ),
  StreamBuilder<QuerySnapshot>(
  stream: _usersStream,
  builder: (BuildContext context,
   AsyncSnapshot<QuerySnapshot> snapshot) {
   if (snapshot.hasError) {
   return const Text('Something went wrong');
   }
   if (snapshot.connectionState == ConnectionState.waiting) {
   return const Text("Loading");
   }
   return ListView(
   shrinkWrap: true,
   children:
   snapshot.data!.docs.map((DocumentSnapshot document) {
   Map<String, dynamic> data =
    document.data()! as Map<String, dynamic>;
   return ListTile(
   title: Text(data['name']),
   );
   }).toList(),
   );
  })
  ],
 ),
 ),
 ),
 );
}
}

コードスニペットの説明

上記のコードでは、Flutterアプリケーションに必要なプラグインをインポートしました。

(注:FirestoreにはFirebaseコアが必要なため、それをpubspec.YAMLファイルに追加し、アプリケーションにもインポートしました。)

以下のコードは、Firebaseをアプリに初期化します。補足として、ウィジェットを作成するとき、データベースにテキストフィールドと現在のユーザーのリストがあります。ウィジェットをでラップし、重複を避けるためにプロパティをSingleChildScrollView設定しました。ListView ShrinkWraptrue

WidgetsFlutterBinding.ensureInitialized();

await Firebase.initializeApp();

以下のコードは主要なパワーハウスです—CloudFirestoreからの読み取り機能を実行します。

final Stream<QuerySnapshot> _usersStream =
 FirebaseFirestore.instance.collection('users').snapshots();

ユーザーコレクションのインスタンスを取得し、それをStream<QuerySnapshot>変数に格納します。

以下のコードはFlutterウィジェットです。これにより、データベースのデータスナップショットに変更があった場合にウィジェットの状態を更新するストリームが作成されます。すべてのユーザーのリストが表示されます。

StreamBuilder<QuerySnapshot>(
  stream: _usersStream,
  builder: (BuildContext context,
   AsyncSnapshot<QuerySnapshot> snapshot) {
   if (snapshot.hasError) {
   return const Text('Something went wrong');
   }
   if (snapshot.connectionState == ConnectionState.waiting) {
   return const Text("Loading");
   }
   return ListView(
   shrinkWrap: true,
   children:
   snapshot.data!.docs.map((DocumentSnapshot document) {
   Map<String, dynamic> data =
    document.data()! as Map<String, dynamic>;
   return ListTile(
   title: Text(data['name']),
   );
   }).toList(),
   );
  })
  )

ファイヤーストア書き込み操作

書き込み操作を実行するには、最初にコレクションインスタンスと、ユーザーテキスト入力を保持する変数を作成します。例を次に示します。

CollectionReference users = FirebaseFirestore.instance.collection('users');
String name = '';

次に、CloudFirestoreを使用してデータベースにドキュメントを挿入する関数を作成します。

Future<void> addUser() {
 // Call the user's CollectionReference to add a new user
 return users
  .add({
  'name': name, // John Doe
 })
  .then((value) => print("User Added"))
  .catchError((error) => print("Failed to add user: $error"));
}

コードにボタンウィジェットを追加しonPressed、名前変数をテキストフィールドの内容で更新するように関数を設定しました。コードベースは次のようになります。

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

Future<void> main() async {
 WidgetsFlutterBinding.ensureInitialized();
 await Firebase.initializeApp();
 runApp(const MyApp());
}

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

 // This widget is the root of your application.
 @override
 Widget build(BuildContext context) {
 return MaterialApp(
  title: 'Flutter Demo',
  theme: ThemeData(
  primarySwatch: Colors.blue,
  ),
  home: const MyHomePage(title: 'Flutter Demo Home Page'),
 );
 }
}

class MyHomePage extends StatefulWidget {
 const MyHomePage({Key? key, required this.title}) : super(key: key);

 final String title;

 @override
 State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
 final Stream<QuerySnapshot> _usersStream =
  FirebaseFirestore.instance.collection('users').snapshots();

 CollectionReference users = FirebaseFirestore.instance.collection('users');

 String name = '';

 Future<void> addUser() {
 // Call the user's CollectionReference to add a new user
 return users
  .add({
  'name': name, // John Doe
 })
  .then((value) => print("User Added"))
  .catchError((error) => print("Failed to add user: $error"));
 }

 @override
 Widget build(BuildContext context) {
 return Scaffold(
  appBar: AppBar(
  title: Text(widget.title),
  ),
  body: SingleChildScrollView(
  child: Container(
   margin: EdgeInsets.symmetric(
    vertical: MediaQuery.of(context).size.height * 0.04,
    horizontal: MediaQuery.of(context).size.width * 0.04),
   child: Column(
   mainAxisAlignment: MainAxisAlignment.start,
   crossAxisAlignment: CrossAxisAlignment.start,
   children: <Widget>[
    const Text(
     'Enter user name',
    style: TextStyle(fontSize: 16),
    ),
    const SizedBox(
    height: 10,
    ),
    TextField(
    onChanged: (value) {
     //Do something with the user input.
     name = value;
    },
    decoration: const InputDecoration(
     hintText: 'Enter your password.',
     contentPadding:
      EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
     border: OutlineInputBorder(
     borderRadius: BorderRadius.all(Radius.circular(6.0)),
     ),
    ),
    ),
    const SizedBox(
    height: 5,
    ),
    ElevatedButton.icon(
     onPressed: (){
     addUser();
    }, icon: Icon(Icons.add), label: Text('Add user')),
    const SizedBox(
    height: 20,
    ),
    StreamBuilder<QuerySnapshot>(
     stream: _usersStream,
     builder: (BuildContext context,
      AsyncSnapshot<QuerySnapshot> snapshot) {
     if (snapshot.hasError) {
      return const Text('Something went wrong');
     }
     if (snapshot.connectionState == ConnectionState.waiting) {
      return const Text("Loading");
     }
     return ListView(
      shrinkWrap: true,
      children:
       snapshot.data!.docs.map((DocumentSnapshot document) {
      Map<String, dynamic> data =
       document.data()! as Map<String, dynamic>;
      return ListTile(
       title: Text(data['name']),
      );
      }).toList(),
     );
     })
   ],
   ),
  ),
  ),
 );
 }
}

その他のCloudFirestore関数は、
https ://firebase.flutter.dev/docs/firestore/usage/に一覧表示されています。

(注:Cloud Firestoreでは、フィルターをチェーンし、1つのクエリでプロパティのフィルター処理と並べ替えを組み合わせることができます。)

リアルタイムデータベース

Firebaseバックエンドプロジェクトの設定は、Cloud Firestoreで行ったものと似ていますが、データベースを選択するときに、FirestoreデータベースではなくRealtimeデータベースを選択する点が異なります。

Flutterアプリケーション

このセクションでは、CloudFirestoreとは異なるプラグインを使用します。したがって、このpubspec.YAMLファイルでは、Firebase_databaseを依存関係として追加します。Flutterアプリケーションでは、以下の手順に従う必要があります。

まず、Firebase_databaseをDartファイルにインポートします。

import 'package:firebase_database/firebase_database.dart';

次に、アプリケーションを初期化するために、以下のコードを使用します。

WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();

Realtime DatabaseはデータをJSONとして保存するため、を介してデータのノードにアクセスできることに注意してくださいDatabaseReference。たとえば、次のようにデータを保存すると、検索ごとに参照を作成できます。あれは:

{
 "users":
   “One”: {
  "name": "Ade"
 },
   “Two”: {
  "name": "Bisi"
 },
   ‘Three”: {
  "name": "David"
 },
   ‘Four”: {
  "name": "Claire"
 }
}

パスを指定することで、ノードへの参照を作成できます。

  • users /:「users」オブジェクト全体への参照を作成します
  • users / One:「One」ユーザーオブジェクトへの参照を作成します
  • users / Two / name:プロパティへの参照を作成します(「Bisi」の値を使用)
DatabaseReference ref = FirebaseDatabase.instance.ref("voters/1/users/1");

(注:パスを指定しない場合、参照はデータベースのルートを指します。)

リアルタイムデータベースへのデータの追加

このセクションでは、Firestoreで行ったのと同じように、新しいユーザーを追加してデータベースにデータを書き込みます。これを行うには、次の手順に従う必要があります。

まず、書き込みたいパスへの参照を作成します。

final refDataInstance = FirebaseDatabase.instance.reference().child('users');

以下に、Realtimeデータベースからデータを読み取り、新しいユーザーをデータベースに書き込む完全なコードを示します。

import 'package:firebase_database/ui/firebase_animated_list.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';

Future<void> main() async {
 WidgetsFlutterBinding.ensureInitialized();

 var app = await Firebase.initializeApp();
 runApp(MaterialApp(
  title: 'Flutter Demo',
  theme: ThemeData(
  primarySwatch: Colors.blue,
  ),
  home: MyHomePage(app: app, title: 'Flutter Demo')));
}

class MyHomePage extends StatefulWidget {
 final FirebaseApp app;

 const MyHomePage({Key? key, required this.title, required this.app})
  : super(key: key);

 final String title;

 @override
 State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
 final refDataInstance = FirebaseDatabase.instance.reference().child('users');

 String name = '';

 @override
 Widget build(BuildContext context) {
 return Scaffold(
  appBar: AppBar(
  title: Text(widget.title),
  ),
  body: SingleChildScrollView(
  child: Container(
   height: MediaQuery.of(context).size.height,
   margin: EdgeInsets.symmetric(
    vertical: MediaQuery.of(context).size.height * 0.04,
    horizontal: MediaQuery.of(context).size.width * 0.04),
   child: Column(
   mainAxisAlignment: MainAxisAlignment.start,
   crossAxisAlignment: CrossAxisAlignment.start,
   children: <Widget>[
    const Text(
    'Enter user name',
    style: TextStyle(fontSize: 16),
    ),
    const SizedBox(
    height: 10,
    ),
    TextField(
    onChanged: (value) {
     //Do something with the user input.
     name = value;
    },
    decoration: const InputDecoration(
     hintText: 'Enter your password.',
     contentPadding:
      EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
     border: OutlineInputBorder(
     borderRadius: BorderRadius.all(Radius.circular(6.0)),
     ),
    ),
    ),
    const SizedBox(
    height: 5,
    ),
    ElevatedButton.icon(
     onPressed: () {
     // adds new user to DB
     refDataInstance.push().child('name').set(name).asStream();
     },
     icon: const Icon(Icons.add),
     label: const Text('Add user')),
    const SizedBox(
    height: 20,
    ),
    Flexible(
     child: FirebaseAnimatedList(
    shrinkWrap: true,
    query: refDataInstance,
    itemBuilder: (BuildContext context, DataSnapshot snapshot,
     Animation<double> animation, int index) {
     return ListTile(
     title: Text(snapshot.value['users']),
     );
    },
    )),
   ],
   ),
  ),
  ),
 );
 }
}

リアルタイムデータベースへの書き込み

以下の式を使用して、書き込み操作を実行します。データベース参照のインスタンスを使用して、ウィジェットのonTap関数にname変数の値を書き込むことができます。elevatedButton

refDataInstance.push().child('name').set(name).asStream();

データベースインスタンスからの読み取り

Firebaseのウィジェットを使用するとFirebaseAnimatedList、データベースを変更するたびにライブストリームの書き込みまたは読み取りを実行できます。

FirebaseAnimatedList(
 shrinkWrap: true,
 query: refDataInstance,
 itemBuilder: (BuildContext context, DataSnapshot snapshot,
  Animation<double> animation, int index) {
 return ListTile(
  title: Text(snapshot.value['users']),
 );
 },
)

(注:リアルタイムデータベースでは、複数ではなく1つのプロパティに対して、単一のクエリでデータをフィルタリングまたは並べ替えることができます。)

結論

Cloud Firestoreは、リアルタイムデータベースと比較して複雑なクエリ構造を可能にします。データは(ドキュメントとして)保存されるときに構造化されるため、CloudFirerstoreで面倒なクエリを実行できます。

リアルタイムデータベースのように複数のプロパティのみを使用するのではなく、1つのプロパティのみを使用して単一のクエリでデータをフィルタリングまたは並べ替えることを選択できます。Cloud Firestoreでは、フィルターをチェーンし、単一のクエリでプロパティのフィルタリングと並べ替えを組み合わせることができます。

データを降順でフェッチする場合、Cloud Firestoreは、Realtime Databaseがクエリ機能を提供しない場合に非常に便利です。また、複数の「where」メソッドをチェーンして、Cloud Firestoreでより具体的なクエリ(論理積)を作成することもできます。

users.whereEqualTo("name", "Bisi").whereEqualTo("vote", 0);

これらの理由から、Flutterアプリケーションに最適なクエリ機能を備えたデータベースを探す場合は、CloudFirestoreを強く推奨します。上記のいくつかのサンプルを使用して、CloudFirestoreがFirebaseの対応物をどのようにエッジングするかを見てきました。

ハッピーコーディング💻

リンク:https ://blog.logrocket.com/google-cloud-firestore-realtime-database-flutter/

#flutter  #google   #firestore 

FlutterのGoogleCloudFirestoreとRealtimeDatabase
Brandon  Schumm

Brandon Schumm

1646211207

How to Create A Shimmer Effect in Flutter with Firebase Firestore

Firestore and Flutter Web connection, Read data from Firestore to flutter web apps with Shimmer Effect.

#firestore #flutter  

How to Create A Shimmer Effect in Flutter with Firebase Firestore

Vue Keep: Google Keep Clone with Vue, Typescript and Firestore

Vue Keep

A Google Keep clone with Vue, Typescript and Firestore.

Demo: https://vue-keep-sepia.vercel.app/

Usage

Create a .env.local file at the root path and enter your firebase project creds:

VUE_APP_FB_API_KEY=
VUE_APP_FB_AUTH_DOMAIN=
VUE_APP_FB_DATABASE_URL=
VUE_APP_FB_PROJECT_ID=
VUE_APP_FB_STORAGE_BUCKET=
VUE_APP_FB_MESSAGING_SENDER_ID=
VUE_APP_FB_APP_ID=
# Install dependencies
$ npm install

# Compiles and hot-reloads for development
$ npm run serve

# Compiles and minifies for production
$ npm run build

# Lints and fixes files
$ npm run lint

Author: wobsoriano
Source Code: https://github.com/wobsoriano/vue-keep
License: MIT

#typescript #vue #firestore 

Vue Keep: Google Keep Clone with Vue, Typescript and Firestore
Dylan  Iqbal

Dylan Iqbal

1642573302

How to Build a Real Time Chat Application in SwiftUI with Firebase

Build a SwiftUI chat app with Firestore from scratch

💬 Build a chat application with real-time updates from scratch in SwiftUI, with Firebase Firestore
In this tutorial, you'll learn how to code all the components required that make up the chat view, create and configure a Firebase project, connect Firebase to the app, and read from and write to Firestore, with real-time updates - meaning the chat conversation will be updated instantly when a new message is added to Firestore.

🎞 Video timestamps
➡ Part 1 - Create project, components and model
0:00 - Introduction
1:40 - Create Xcode project
2:51 - Update Assets folder
4:34 - Code the TitleRow
9:03 - Create the Message model
10:31 - Code the MessageBubble

➡ Part 2 - Finish UI and configure Firebase
18:34 - Code the MessageField
23:24 - Create Firebase project
26:01 - Add Firebase SDK and initialization code
28:29 - Create Firestore database
29:34 - Add data to Firestore

➡ Part 3 - Read and write with Firestore
32:07 - Call the data with real-time updates
40:13 - Writing to Firestore
43:42 - Scroll to last message
48:04 - Conclusion

🔗 Links mentioned in the video:
➡ Unsplash: https://unsplash.com/ 
➡ Firebase Console: https://console.firebase.google.com/ 
➡ Firebase iOS SDK Github repo: https://github.com/firebase/firebase-ios-sdk 
➡ Cloud Firestore Data model: https://firebase.google.com/docs/firestore/data-model 
➡ ScrollViewReader documentation: https://developer.apple.com/documentation/swiftui/scrollviewreader 
➡ scrollTo(_:anchor:) documentation: https://developer.apple.com/documentation/swiftui/scrollviewproxy/scrollto(_:anchor:) 

✏️ Watch without ads, and access the written version and source files:
➡ Part 1: https://designcode.io/quick-apps-swiftui-chat-app-1 
➡ Part 2: https://designcode.io/quick-apps-swiftui-chat-app-2 
➡ Part 3: https://designcode.io/quick-apps-swiftui-chat-app-3 

👩🏻‍💻 Source code on Github:
https://github.com/stephdiep/ChatApp 

#firebase #firestore #swift #swiftui

How to Build a Real Time Chat Application in SwiftUI with Firebase

Firebase Firestore (Version 9) CRUD con JavaScript

Firebase Firestore (Version 9) CRUD con Javascript

Aprende a crear una aplicación web de Javascript que usa Firebase como backend. En este ejemplo aprenderemos a crear un CRUD (Create, React, Update, Delete) que usa Firestore como base de datos NoSQL en tiempo real.

Indice del Tutorial:
00:00 Introducción
01:12 Project Setup
14:06 Firestore Setup
30:14 Listar Datos
44:17 Eliminar Datos
56:44 Editar Datos
01:06:20 Actualizar Datos
01:13:02 Estilizar con Bootstrap5

Código del Ejemplo: https://github.com/FaztWeb/firebase-crud-javascript

#javascript #firebase #crud #firestore #nosql 

Firebase Firestore (Version 9) CRUD con JavaScript