Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Qual a melhor maneira de adicionar uma nova coluna no modelo quando se utilizia o Firebase,

Pessoal, boa noite.

Eu tenho um app em produção, para quem deseja conhecer (https://play.google.com/store/apps/details?id=br.com.site10consultoria.bettao) e preciso adicionar uma nova coluna no modelo:

import 'package:cloud_firestore/cloud_firestore.dart';

class ActivityModel{

String id;
Timestamp activityDate;
String title;
String userId;
String itemId;
String item;
String? description;
String? shopId;
String? videoLink;
List<String>? images;

ActivityModel({
  required this.id,
  required this.activityDate,
  required this.title,
  required this.userId,
  required this.itemId,
  required this.item,
  this.description,
  this.shopId,
  this.videoLink,
  this.images,
});

ActivityModel.fromMap(Map<String, dynamic> map):
  id = map["id"],
      activityDate = map["activityDate"],
      title = map["title"],
      userId = map["userId"],
      itemId = map["itemId"],
      item = map["item"],
      description = map["description"],
      shopId = map["shopId"],
      videoLink = map["videoLink"];

Map<String, dynamic> toMap(){
    return {
      "id": id,
      "activityDate": activityDate,
      "title": title,
      "userId": userId,
      "itemId": itemId,
      "item": item,
      "description": description,
      "shopId": shopId,
      "videoLink": videoLink,
    };
  }

}

Para ler os dados e utilizar no app eu uso a função abaixo:

loadData() {
    if (widget.activity != null) {

      _idController.text = widget.activity!['id'];
      _titleController.text = widget.activity!['title'];
      activityDate = widget.activity!['activityDate'].toDate();
      _itemIdController.text = widget.activity!['itemId'];

      if (widget.activity!['description'] != null) {
        _descriptionController.text = widget.activity!['description'];
      }
    }
  }

Só que quando adiciono um novo campo tipo String description2, buga tudo. O app já está em produção, então qualquer alteracão trava todos os usuários.

Tem alguma forma de tratar isso?

Colocar dentro de algum try/catch?

2 respostas
solução!

Olá Celso, boa noite!

Entendo sua preocupação em adicionar uma nova coluna ao seu modelo sem causar problemas aos usuários que já estão utilizando o app principalmente se for em produção. Vamos abordar isso de uma maneira que minimize os riscos.

Primeiramente, você pode adicionar o novo campo description2 ao seu modelo ActivityModel da seguinte maneira:

class ActivityModel {
  String id;
  Timestamp activityDate;
  String title;
  String userId;
  String itemId;
  String item;
  String? description;
  String? shopId;
  String? videoLink;
  List<String>? images;
  String? description2; // Novo campo adicionado

  ActivityModel({
    required this.id,
    required this.activityDate,
    required this.title,
    required this.userId,
    required this.itemId,
    required this.item,
    this.description,
    this.shopId,
    this.videoLink,
    this.images,
    this.description2, // Novo campo adicionado
  });

  ActivityModel.fromMap(Map<String, dynamic> map)
      : id = map["id"],
        activityDate = map["activityDate"],
        title = map["title"],
        userId = map["userId"],
        itemId = map["itemId"],
        item = map["item"],
        description = map["description"],
        shopId = map["shopId"],
        videoLink = map["videoLink"],
        description2 = map["description2"]; // Novo campo adicionado

  Map<String, dynamic> toMap() {
    return {
      "id": id,
      "activityDate": activityDate,
      "title": title,
      "userId": userId,
      "itemId": itemId,
      "item": item,
      "description": description,
      "shopId": shopId,
      "videoLink": videoLink,
      "description2": description2, // Novo campo adicionado
    };
  }
}

Para garantir que o app não quebre ao tentar acessar o novo campo, você pode usar um operador ternário ou um try/catch ao carregar os dados. Abaixo está um exemplo de como você pode ajustar a função loadData:

loadData() {
  if (widget.activity != null) {
    _idController.text = widget.activity!['id'];
    _titleController.text = widget.activity!['title'];
    activityDate = widget.activity!['activityDate'].toDate();
    _itemIdController.text = widget.activity!['itemId'];

    if (widget.activity!['description'] != null) {
      _descriptionController.text = widget.activity!['description'];
    }

    // Adicionando o novo campo description2 com verificação
    if (widget.activity!.containsKey('description2') && widget.activity!['description2'] != null) {
      _description2Controller.text = widget.activity!['description2'];
    }
  }
}

Dessa forma, você verifica se o campo description2 existe e se não é nulo antes de tentar acessá-lo. Isso ajuda a evitar que o app quebre caso o campo não esteja presente nos dados antigos.

Testa e veja se faz sentido no seu código.

Espero ter ajudado. Qualquer dúvida manda aqui. Bons estudos.

Obrigado.

Como trabalho também com DocumentSnapShot tive de fazer algumas alterações, mas funcionou.