Antonio Guedes
Antonio Guedes21/04/2025 19:18
Compartilhe

Firebase Realtime Database: Como Regras de Segurança (quase) travaram meu projeto de Jogo da Velha

    Você já teve aquela sensação de que o código está certo, mas simplesmente não funciona? Foi o que vivi no desenvolvimento de um projeto pessoal usando o Firebase Realtime Database. O jogo da velha multiplayer estava no ar, mas a partida nunca começava. 😵‍💫

    A causa? Regras de segurança mal compreendidas.

    Neste artigo compartilho o erro, a descoberta, a solução e um lembrete: “Não é sobre o jogo. É sobre quebrar padrões.

    🔍 O problema

    Ao testar o projeto, percebi que os jogadores se conectavam, mas a partida não iniciava. Após diversas revisões no código, identifiquei que o Firebase estava negando a alteração da chave isFull, impedindo que o jogo começasse.

    O motivo era claro (depois que eu entendi): as regras de segurança estavam mal configuradas e esperavam uma estrutura de dados que nem existia no meu banco.

    🛠️ A estrutura esperada no banco de dados

    O Firebase aguardava que os dados dos jogadores estivessem registrados em uma estrutura chamada userGames, mas essa parte nunca foi implementada. Por isso, as permissões eram negadas.

    A estrutura real do banco no projeto era assim:

    games
     └── game
        └── $matchId
             ├── players
             │    ├── player1
             │    └── player2
             ├── isFull
             ├── currentPlayer
             ├── eventos
             └── moves
    

    🔐 A Regra de Segurança que me travou

    As regras originais tentavam validar algo assim:

    "players": {
    "player1": {
      ".write": "root.child('userGames/' + auth.uid + '/' + $matchId + '/playerId').val() === data.child('id').val() || !data.exists()"
    },
    "player2": {
      ".write": "root.child('userGames/' + auth.uid + '/' + $matchId + '/playerId').val() === data.child('id').val() || !data.exists()"
    }
    }
    

    Ou seja, a permissão era baseada em uma verificação que sempre falhava, pois userGames não existia.

    ✅ A correção que funcionou

    Depois de estudar a documentação oficial do Firebase, reestruturei as regras com base na presença dos jogadores dentro da própria estrutura do jogo:

    "players": {
    "player1": {
      ".write": "!data.exists()"
    },
    "player2": {
      ".write": "!data.exists() && root.child('games/game' + $matchId + '/players/player1').exists()"
    }
    },
    "isFull": {
    ".read": "auth != null",
    ".write": "!data.exists() || (root.child('games/game' + $matchId + '/players/player1').exists() && root.child('games/game' + $matchId + '/players/player2').exists())"
    }
    

    Agora sim! O jogo reconhece a presença dos dois jogadores e altera a chave isFull para true, permitindo o início da partida. 🎮

    📚 O que aprendi com isso?

    • Não subestime a documentação.
    • Regras de segurança são parte essencial do backend.
    • Estude a ferramenta antes de usá-la.
    • E o mais importante: “Imperfeito feito vence, perfeito nunca feito.”

    Esse projeto é parte de uma série que estou escrevendo para documentar como estou quebrando padrões de procrastinação e evoluindo como dev.

    Se você também está enfrentando desafios nos seus projetos, saiba que você não está sozinho.

    ---

    📌 Repositório no GitHub

    🧠 Documentação de Regras do Firebase

    ✍️ Leia os posts anteriores da série no blog

    Compartilhe
    Comentários (0)