Flutter: Ukládání dat

Z MiS
Přejít na: navigace, hledání


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