Atualizando aplicação Flutter para null safe - exemplo prático
Tags: flutter, mobile, update
Published: 2023-03-06 19:58:15

### Não comece errado

Antes de tudo tenho que saber que minha aplicação funciona na versão sem `null safety` que estou usando, isso no dará tranquilidade para resolver apenas problemas relacionados à atualização do Flutter.

### Motivação

A aplicação alvo é o POC https://github.com/GeoSales-Evolution/unleash-multi-tenant-flutter-poc.  
Estávamos usando o Flutter `1.22.2` para rodá-la, e agora queremos mudar para `2.5.0`. O porquê dessa escolha além do uso do no `null safe` está relacionada com outros projetos que se interagem com o POC.

### Montando o experimento
No caso montamos um fluxo na aplicação funcionando e o esperado é que após a migração para a `2.5.0` a aplicação funcione da mesma maneira.

No fluxo: 
Usuário entra com `Login` e `Tenant` > é levado a tela de sonsulta de flags > digita um flag ativa > recebe a string 'flag ativa? == true' no console do terminal. 
Essa flags são `Feature Flags` de um projeto no GitLab.  

Abaixo prints do fluxo funcionando:  


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/grso4xjfx5fk35llicrf.png)  


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wx5hrrgjn1dp8ynr68zz.png)  

### Subindo as dependências
O próprio [Flutter](https://dart.dev/null-safety/migration-guide#step1-wait) sugere que atualizemos primeiro as dependências em ordem para depois atualizar as aplicações.  

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u0nz1c26koplduvqkas6.png)


Como não temos nenhum subprojeto como dependência do nosso app vamos direto ao seu `pubspec.yaml`, observamos as versões dos pacotes(`packages`) usados e procuramos no https://pub.dev/ quais versões estão disponíveis com o nosso Flutter e Dart SDK almejados.

Por exemplo: `path_provider:` está na versão `^1.6.28` e podemos observar na sua página de [versões path_provider](https://pub.dev/packages/path_provider/versions) que uma versão que tem `null safety` e atende no `Dart SDK 14`(Flutter 2.5.0) pode ser a `2.0.0`.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l1ylrhhwe4c8e9a8kfjy.png)

Além disso, vamos atualizar a versão do Flutter e do Dart SDK no no `pubspec.yaml`, no nosso caso 2.5.0 e 2.14.0 respectivamente.

### Dart pub upgrade
Depois decididas todas as mudanças de versões das dependências usamos uma ferramente altomatizado do dart para resolver as dependências:  

```dart pub upgrade```  

Se houver alguma incompatibilidade entre as dependências o `Dart` vai avisar.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ml5j28a6pk11bvhre0a0.png)

`dart pub get` funciona também, porém prefiro `upgrade` por ser mais verboso.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aw55o97l5un9yyhgxp85.png)

### dart migrate
```dart migrate```  
na raiz do projeto vai fornce um relatório de problemas a serem corrigidos.  
Nós esperamos dois tipos de erros: adequação ao `null safety` e quebra de APIs(causadas por mudanças nas APIs das dependências depois de atualizações).  

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u7hx5j8npvskcd1udds6.png)

Concertamos os problemas com `null safety` e adaptamos o código para as novas APIs das dependências. Conforme o tamanho do seu projeto esse vai ser o passo mais demorado.  
Então rodamos `dart migrate` novamente e esperamos ver:  


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b9kj3ud42drz6d0laqg3.png)

### Rodar aplicação atualizada
```flutter run```  
deve funcionar normalmente depois das alterações e mostrar uma mensagem:

```💪 Running with sound null safety 💪```

Nos resta testar a aplicação. Nesse caso estou considerando o fluxo do experimento que definimos anteriormente, e ele funcionou sem falhas conforme a captura abaixo:  

![flutter run](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8rbsibc9b3w9z4e1tqi6.png)


O experimento não encontrou evidências de que a aplicação contém defeito(quem sabe a discussão sobre como usar experimento em outro post), logo abrimos [pull request]().

Valeu !