Flutter: Ukládání dat

Z MiS
(Rozdíly mezi verzemi)
Přejít na: navigace, hledání
(Struktura dat ve Firestore: Doplněny možné podoby – aplikace.)
(Nastavení projektu pro Firebase: Doplněno ověření přihlášení do firebase.)
 
(Není zobrazeno 6 mezilehlých verzí od 1 uživatele.)
Řádka 177: Řádka 177:
 
== Google Firestore ==
 
== Google Firestore ==
  
* Google Firestore je cloudová NoSQL databáze od Google, která je součástí platformy Firebase.  
+
* Cloud Firestore je cloudová NoSQL databáze od Google, která je součástí platformy Google Firebase.  
  
; Vlastnosti
+
=== Vlastnosti Cloud Firestore ===
 +
 
 +
; Výhody a nevýhody
 
* Firebase je dobře integrovaná do frameworku Flutter (Flutter také vyvíjí Google)
 
* Firebase je dobře integrovaná do frameworku Flutter (Flutter také vyvíjí Google)
 
* Data se ukládají do cloudu – data může sdílet mobilní i webová aplikace
 
* Data se ukládají do cloudu – data může sdílet mobilní i webová aplikace
 
* Synchronizace dat v reálném čase
 
* Synchronizace dat v reálném čase
 +
* Pro přístup k datům je potřeba připojení k internetu
 
* Pro malé projekty stačí varianta zdarma (pro větší bude třeba platit)
 
* Pro malé projekty stačí varianta zdarma (pro větší bude třeba platit)
  
=== Struktura dat ve Firestore ===
+
; Struktura dat ve Firestore
 
* Data se neukládají do entit jako u ER databází – spíše jako několik seznamů objektů.
 
* Data se neukládají do entit jako u ER databází – spíše jako několik seznamů objektů.
  
; Pojmy:
+
Pojmy
 
* Dokument (Document) ... konkrétní záznam (jako jeden řádek v databázi) – například údaje o jednom uživateli.
 
* Dokument (Document) ... konkrétní záznam (jako jeden řádek v databázi) – například údaje o jednom uživateli.
 
* Pole (Field) ... konkrétní hodnota (atribut) – například jméno uživatele
 
* Pole (Field) ... konkrétní hodnota (atribut) – například jméno uživatele
Řádka 207: Řádka 210:
 
           └── email: "jan@email.cz"
 
           └── email: "jan@email.cz"
  
=== Vytvoření projektu ve Firebase===
+
=== Nastavení projektu pro Firebase===
  
 +
; Založení projektu na webu Firebase
 
#Jdi na: [https://console.firebase.google.com Console.firebase.google.com]
 
#Jdi na: [https://console.firebase.google.com Console.firebase.google.com]
#Klikni na Vytvořit projekt
+
#Klikni na Vytvořit projekt a zadej název projektu
#Zadej název projektu
+
 
#Po vytvoření přidej aplikaci (Android / iOS / Web)
 
#Po vytvoření přidej aplikaci (Android / iOS / Web)
  
===Propojení Flutter aplikace s Firebase===
+
; Instalace FlutterFire CLI
 +
# Nainstaluj Firebase CLI podle [https://firebase.google.com/docs/cli návodu z  Firebase.google.com > CLI]
 +
#* Bude nejspíš vyžadovate heslo správce počítače.
 +
# Přihlaš se: <code>firebase login</code>
 +
#* Musíš rozhodnout, jestli budeš využívat Google Gemini v rámci Firebase a jestli může Google využívat statistická data.
 +
#* Zvolíš účet Google, pod kterým budeš pracovat
 +
#* Ověř funkčnost pomocí: <code>firebase projects:list</code> – mělo by vypsat seznam založených projektů
 +
# Založ projekt ve Flutteru jako obvykle
 +
# Ve složce projektu spusť aktivaci FlutterFire CLI:
 +
#: <code>dart pub global activate flutterfire_cli</code>
 +
#: <code>flutterfire configure --project='''nazev-projektu'''</code>
 +
#: Do projektu tím přibude konfigurační soubor: <code>lib/firebase_options.dart</code>
  
 +
<!-- Podle ChatGPT – ale neodpovídá návodu na Firebase:
 
Ve Flutter projektu spusť:
 
Ve Flutter projektu spusť:
  
 
  flutter pub add firebase_core
 
  flutter pub add firebase_core
 
  flutter pub add cloud_firestore
 
  flutter pub add cloud_firestore
 +
-->
  
Poté inicializuj Firebase v main.dart:
+
; Inicializuj Firebase v main.dart:
 
+
import 'package:firebase_core/firebase_core.dart';
 +
import 'firebase_options.dart';
 +
 +
// ...
 +
 +
await Firebase.initializeApp(
 +
    options: DefaultFirebaseOptions.currentPlatform,
 +
);
 +
<!-- Původní podle ChatGPT
 
  import 'package:firebase_core/firebase_core.dart';
 
  import 'package:firebase_core/firebase_core.dart';
 
  import 'package:flutter/material.dart';
 
  import 'package:flutter/material.dart';
Řádka 231: Řádka 255:
 
   runApp(MyApp());
 
   runApp(MyApp());
 
  }
 
  }
 +
-->
 +
 +
; Další plug-iny importuj dle potřeby viz dále
  
=== Ukládání dat do Firestore===
+
=== Import Firestore ===
  
; Importuj Firestore:
+
Import:
  
 
  import 'package:cloud_firestore/cloud_firestore.dart';
 
  import 'package:cloud_firestore/cloud_firestore.dart';
  
; Vytvoření instance pro přístup k databázi:
+
Vytvoření instance pro přístup k databázi:
  
 
  final FirebaseFirestore db = FirebaseFirestore.instance;
 
  final FirebaseFirestore db = FirebaseFirestore.instance;
  
; Přidání nového dokumentu
+
=== Přidání nového dokumentu ===
 
  await db.collection('users').add({
 
  await db.collection('users').add({
 
   'name': 'Jan',
 
   'name': 'Jan',
Řádka 267: Řádka 294:
 
  }
 
  }
  
===Načtení v reálném čase ===
+
=== Čtení v reálném čase ===
  
 
Firestore umožňuje poslouchat změny. Data se pak automaticky aktualizují, pokud proběhne změna v databázi (například z jiného zařízení připojeného ke stejnému projektu):
 
Firestore umožňuje poslouchat změny. Data se pak automaticky aktualizují, pokud proběhne změna v databázi (například z jiného zařízení připojeného ke stejnému projektu):
Řádka 298: Řádka 325:
  
 
; Smazání dokumentu
 
; Smazání dokumentu
await db.collection('users').doc('student1').delete();
+
await db.collection('users').doc('student1').delete();
  
 
=== Bezpečnostní pravidla (Rules) ===
 
=== Bezpečnostní pravidla (Rules) ===
Řádka 316: Řádka 343:
  
 
=== Zdroje ===
 
=== Zdroje ===
* Sekce o Firebase byla vytvořena pomocí služby [https://www.chatgpt.com ChatGPT].
+
* Základ sekce o Firebase byl vytvořen pomocí služby [https://www.chatgpt.com ChatGPT].
 +
* [https://console.firebase.google.com/ Console.firebase.google.com > Postup nastavení projektu]
 +
* [https://www.youtube.com/playlist?list=PLl-K7zZEsYLluG5MCVEzXAQ7ACZBCuZgZ YouTube.com > Get to know Cloud Firebase] (seriál videí)
 
* [https://cloud.google.com/firestore/pricing Google Cloud > Firestore Pricing]
 
* [https://cloud.google.com/firestore/pricing Google Cloud > Firestore Pricing]
 
 
  
 
== Vlastní backend: ServerPod ==
 
== Vlastní backend: ServerPod ==

Aktuální verze z 23. 2. 2026, 06:14


Pro trvalé uložení dat i po vypnutí aplikace můžeme data uložit:

Následuje několik příkladů možných řešení.

Obsah

Lokální export: jsonEncode/jsonDecode

Vlastnosti

Postup zápisu

  1. Nalezení umístění souboru:
    • Využij balíček path_provider a metodu getApplicationDocumentsDirectory().
    • Pro zápis do souboru použij třídu File a metodu writeAsString.
  2. Převod dat na JSON
    • Využij balíček dart:convert.
    • Pro parsování JSON využij metodu jsonDecode(list) – výsledkem bude textová reprezentace objektu ve formátu JSON.

Postup čtení

  1. Nalezení umístění souboru:
    • Využij balíček path_provider a metodu getApplicationDocumentsDirectory().
    • Pro čtení souboru použij třídu File a metodu readAsString.
  2. Převod dat na JSON
    • Využij balíček dart:convert.
    • Pro ukládání využij metodu jsonEncode(list) – výsledkem bude textová reprezentace objektu ve formátu JSON.

Ukázka použití v aplikaci

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:convert';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Úložiště Demo',
      home: HomePage(storage: FileStorage()),
    );
  }
}

class Zaznam {
  final String jmeno;
  final int pocet;

  const Zaznam({ required this.jmeno, required this.pocet, }); 

  // Převod do JSON
  Map<String, dynamic> toJson() => {
    'jmeno': jmeno,
    'pocet': pocet,
  };

  // Obnov z JSON
  factory Zaznam.fromJson(Map<String, dynamic> json) {
    return Zaznam(
      jmeno: (json['jmeno']),
      pocet: json['pocet'] as int,
    );
  }
}

/// Práce se soubory
class FileStorage {
  Future<String> get _localPath async {
    final directory = await getApplicationDocumentsDirectory();
    return directory.path;
  }

  Future<File> get _localFile async {
    final path = await _localPath;
    return File('$path/data.txt');
  }

  Future<String> readFile() async {
    final file = await _localFile;
    return file.readAsString();
  }

  Future<void> writeFile(String content) async {
    final file = await _localFile;
    await file.writeAsString(content);
  }
}

/// Stav aplikace včetně zápisu do souboru
class HomePage extends StatefulWidget {
  final FileStorage storage;
  const HomePage({required this.storage});
  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<Zaznam> _seznam = [];

  @override
  void initState() {
    super.initState();
    _loadData();   // Načtení dat při startu
  }

  Future<void> _loadData() async {
    try {
      final jsonString = await widget.storage.readFile();
      final List<dynamic> decoded = jsonDecode(jsonString);
      setState(() {
        _seznam = decoded
            .map((item) => Zaznam.fromJson(item as Map<String, dynamic>))
            .toList();
      });
    } catch (e) {
      TODO: Zobraz chybové hlášení vhodným způsobem.
    }
  }

  Future<void> _saveData() async {
    final jsonString = jsonEncode(
      _seznam.map((z) => z.toJson()).toList()
    );
    await widget.storage.writeFile(jsonString);
  }

  void _addRecord() {
    setState(() {
      _seznam.add(Zaznam(
        jmeno: 'Josef',
        pocet: 1000,
      ));
    });
    _saveData();
  } 

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // ... vytvoř GUI
    );
  }
}

Tip

 Zdroje


Lokální databáze: Hive

Zdroje


Google Firestore

Vlastnosti Cloud Firestore

Výhody a nevýhody
Struktura dat ve Firestore

Pojmy

Příklad:

users (kolekce)
   └── user1 (dokument)
         ├── name: "Jan"
         ├── age: 18
         └── email: "jan@email.cz"

Nastavení projektu pro Firebase

Založení projektu na webu Firebase
  1. Jdi na: Console.firebase.google.com
  2. Klikni na Vytvořit projekt a zadej název projektu
  3. Po vytvoření přidej aplikaci (Android / iOS / Web)
Instalace FlutterFire CLI
  1. Nainstaluj Firebase CLI podle návodu z  Firebase.google.com > CLI
    • Bude nejspíš vyžadovate heslo správce počítače.
  2. Přihlaš se: firebase login
    • Musíš rozhodnout, jestli budeš využívat Google Gemini v rámci Firebase a jestli může Google využívat statistická data.
    • Zvolíš účet Google, pod kterým budeš pracovat
    • Ověř funkčnost pomocí: firebase projects:list – mělo by vypsat seznam založených projektů
  3. Založ projekt ve Flutteru jako obvykle
  4. Ve složce projektu spusť aktivaci FlutterFire CLI:
    dart pub global activate flutterfire_cli
    flutterfire configure --project=nazev-projektu
    Do projektu tím přibude konfigurační soubor: lib/firebase_options.dart


Inicializuj Firebase v main.dart
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';

// ...

await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
);
Další plug-iny importuj dle potřeby viz dále

Import Firestore

Import:

import 'package:cloud_firestore/cloud_firestore.dart';

Vytvoření instance pro přístup k databázi:

final FirebaseFirestore db = FirebaseFirestore.instance;

Přidání nového dokumentu

await db.collection('users').add({
  'name': 'Jan',
  'age': 18,
  'email': 'jan@email.cz',
});

Tím se:

  1. vytvoří kolekce users (pokud neexistuje)
  2. přidá nový dokument s automatickým ID
Uložení dokumentu s vlastním ID
await db.collection('users').doc('student1').set({
  'name': 'Petra',
  'age': 17,
});

Čtení dat z Firestore jednorázově

var snapshot = await db.collection('users').get();

for (var doc in snapshot.docs) {
  print(doc.data());
}

Čtení v reálném čase

Firestore umožňuje poslouchat změny. Data se pak automaticky aktualizují, pokud proběhne změna v databázi (například z jiného zařízení připojeného ke stejnému projektu):

StreamBuilder(
  stream: db.collection('users').snapshots(),
  builder: (context, snapshot) {
    if (!snapshot.hasData) {
      return CircularProgressIndicator();
    }

    var docs = snapshot.data!.docs;

    return ListView(
      children: docs.map((doc) {
        return ListTile(
          title: Text(doc['name']),
        );
      }).toList(),
    );
  },
);

Aktualizace dat

await db.collection('users').doc('student1').update({
  'age': 18,
});

Smazání dat

Smazání dokumentu
await db.collection('users').doc('student1').delete();

Bezpečnostní pravidla (Rules)

Ve Firebase konzoli nastav pravidla přístupu.

Například pouze pro přihlášené uživatele:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

Zdroje

Vlastní backend: ServerPod

Osobní nástroje
Jmenné prostory
Varianty
Akce
Výuka
Navigace
Nástroje