FireSync
  • Documentação
  • FireSync.APP
    • Bancos de Dados
      • Criação
        • Autorização de IP's
      • Edição
    • Menus
      • Criação
      • Edição
        • Busca Avançada
        • Header
        • Vinculos
    • Dashboards
    • Conta FireSync
      • Integrações
      • Usuários
      • Permissões
  • Serviços
    • Connector
      • NodeJS Modulo
      • Criação de Conector
      • Edição / Acesso
      • API
    • DBRealTime
      • Cliente Javascript
        • Introdução
        • Versão Atual
        • Instalação / Configuração
        • Conceitos Fundamentais
          • Conexão e Autenticação
          • Referência do Banco de Dados (DatabaseReference)
          • Caminhos (path vs relativePath)
          • Snapshot de Dados (DataSnapshot)
          • Chaves Inválidas
        • Guia Rápido / Uso Básico
        • Referência da API
          • Objeto fireSyncClient
          • Classe DatabaseReference
          • Classe DataSnapshot
        • Listeners em Tempo Real (onValue, off)
        • Eventos Públicos (on, off)
        • Tratamento de Erros
        • Exemplo Completo
      • Cliente NodeJS
        • Introdução
        • Instalação
        • Conceitos Fundamentais
          • Inicialização e Configuração
          • Cabeçalho Origin (Obrigatório)
          • Conexão, Estado e Reconexão
          • Autenticação (TOKEN)
          • Referência (DatabaseReference) e Caminhos
          • Snapshot de Dados (DataSnapshot)
          • IDs de Requisição (Uso Interno)
          • Chaves Inválidas
        • Guia Rápido / Uso Básico
        • Referência da API
          • Objeto fireSyncClient
          • Classe DatabaseReference
          • Classe DataSnapshot
        • Listeners em Tempo Real (onValue, off)
        • Eventos Públicos (on, off)
        • Tratamento de Erros
  • FireSync.Tools
    • FireSync Tools
    • XmlToJson
    • QRCode
    • Date
    • PIX
      • QRPIX
      • PIX
  • API Integrações
    • Integrações
    • Entry
    • Query
Fornecido por GitBook
Nesta página
  1. Serviços
  2. DBRealTime
  3. Cliente Javascript

Exemplo Completo

HTML

<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Exemplo Completo FireSyncClient</title>
    <style>
        body { font-family: Arial, sans-serif; line-height: 1.5; margin: 15px; background-color: #f4f4f4; }
        .container { background-color: #fff; padding: 20px; border-radius: 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); margin-bottom: 15px; }
        h1, h2, h3 { border-bottom: 1px solid #eee; padding-bottom: 5px; margin-top: 0; }
        label { display: block; margin-bottom: 3px; font-weight: bold; }
        input[type="text"], textarea, select { width: 95%; max-width: 500px; padding: 8px; margin-bottom: 10px; border: 1px solid #ccc; border-radius: 3px; font-size: 0.95em; }
        textarea { min-height: 60px; font-family: monospace; }
        button { padding: 10px 15px; margin-right: 8px; margin-bottom: 8px; cursor: pointer; border: none; border-radius: 3px; background-color: #007bff; color: white; font-size: 0.95em; }
        button:hover { background-color: #0056b3; }
        button:disabled { background-color: #cccccc; cursor: not-allowed; }
        pre { background-color: #e9e9e9; border: 1px solid #ddd; padding: 10px; max-height: 250px; overflow-y: auto; white-space: pre-wrap; word-wrap: break-word; font-size: 0.9em; border-radius: 3px; }
        hr { border: 0; border-top: 1px solid #eee; margin: 20px 0; }
        .status-ok { color: green; font-weight: bold; }
        .status-error { color: red; font-weight: bold; }
        .status-warn { color: orange; font-weight: bold; }
        .flex-buttons button { flex-grow: 1; margin-left: 4px; margin-right: 4px;}
        .flex-buttons { display: flex; flex-wrap: wrap; margin-left: -4px; margin-right: -4px; }
    </style>
</head>
<body>

    <h1>Exemplo Completo FireSyncClient (v0.3.0)</h1>

    <div class="container">
        <h2>1. Conexão e Autenticação</h2>
        <div>
            <label for="jwt">Token:</label>
            <textarea id="jwt" placeholder="Cole seu TOKEN aqui..."></textarea>
        </div>
        <div class="flex-buttons">
            <button id="connectBtn">Conectar</button>
            <button id="disconnectBtn" disabled>Desconectar</button>
            <button id="goOfflineBtn" disabled>Ficar Offline</button>
            <button id="goOnlineBtn" disabled>Ficar Online</button>
        </div>
        <div>
            <strong>Status:</strong> <span id="connStatus">disconnected</span>
        </div>
        <div>
            <strong>Autenticado:</strong> <span id="authStatus">false</span>
        </div>
        <div>
            <strong>BasePath:</strong> <span id="basePath">-</span>
        </div>
    </div>

    <div class="container" id="dataOps" style="display: none;">
        <h2>2. Operações de Dados</h2>
        <div>
            <label for="pathInput">Caminho Relativo:</label>
            <input type="text" id="pathInput" value="meusDados/item1">
        </div>
        <div>
            <label for="valueInput">Valor (JSON) para Set/Update/Push:</label>
            <textarea id="valueInput" placeholder='Ex: {"nome": "Teste", "valor": 123} ou "uma string" ou 456 ou null'>{"timestamp": 0}</textarea>
        </div>
        <div class="flex-buttons">
            <button id="setBtn">Set</button>
            <button id="updateBtn">Update</button>
            <button id="getBtn">Get</button>
            <button id="removeBtn">Remove</button>
            <button id="pushBtn">Push com Valor</button>
            <button id="pushRefBtn">Push só Ref</button>
        </div>
         <h3>Resultado do Último 'Get':</h3>
         <pre id="getLastResult">(Nenhum get realizado)</pre>
    </div>

    <div class="container" id="listenerOps" style="display: none;">
         <h2>3. Listener em Tempo Real (onValue)</h2>
          <div>
              <label for="listenerPathInput">Path Relativo para Escutar:</label>
              <input type="text" id="listenerPathInput" value="meusDados/item1">
              <button id="toggleListenerBtn">Iniciar Listener</button>
          </div>
           <h3>Dados Recebidos pelo Listener:</h3>
           <pre id="onValueData">(Listener inativo)</pre>
    </div>

     <div class="container">
         <h2>Logs da Aplicação Cliente</h2>
         <pre id="log"></pre>
    </div>

    <script src="https://cdn.firesync.app/clients/fsc.js"></script>

    <script>
        // --- Referências aos Elementos DOM ---
        const jwtInput = document.getElementById('jwt');
        const connectBtn = document.getElementById('connectBtn');
        const disconnectBtn = document.getElementById('disconnectBtn');
        const goOfflineBtn = document.getElementById('goOfflineBtn');
        const goOnlineBtn = document.getElementById('goOnlineBtn');
        const statusSpan = document.getElementById('connStatus');
        const authStatusSpan = document.getElementById('authStatus');
        const basePathSpan = document.getElementById('basePath');
        const dataOpsDiv = document.getElementById('dataOps');
        const listenerOpsDiv = document.getElementById('listenerOps');
        const pathInput = document.getElementById('pathInput');
        const valueInput = document.getElementById('valueInput');
        const setBtn = document.getElementById('setBtn');
        const updateBtn = document.getElementById('updateBtn');
        const getBtn = document.getElementById('getBtn');
        const removeBtn = document.getElementById('removeBtn');
        const pushBtn = document.getElementById('pushBtn');
        const pushRefBtn = document.getElementById('pushRefBtn');
        const getLastResultPre = document.getElementById('getLastResult');
        const listenerPathInput = document.getElementById('listenerPathInput');
        const toggleListenerBtn = document.getElementById('toggleListenerBtn');
        const onValueDataPre = document.getElementById('onValueData');
        const logPre = document.getElementById('log');

        let currentListenerUnsubscribe = null;
        let currentListenerPath = null;

        // --- Funções Auxiliares ---
        function log(message) {
            console.log("[App]", message); // Log no console também
            const now = new Date().toLocaleTimeString();
            logPre.textContent += `[${now}] ${message}\n`;
            logPre.scrollTop = logPre.scrollHeight; // Auto-scroll
        }

        function updateUI() {
            const state = fireSyncClient.getConnectionState();
            const isAuth = fireSyncClient.isAuthenticated();

            statusSpan.textContent = state;
            statusSpan.className = (state === 'authenticated' || state === 'connected') ? 'status-ok' : (state === 'error' || state === 'disconnected') ? 'status-error' : 'status-warn';
            authStatusSpan.textContent = isAuth ? 'Sim' : 'Não';
            authStatusSpan.className = isAuth ? 'status-ok' : 'status-error';
            basePathSpan.textContent = isAuth ? (fireSyncClient.ref().path || '(Raiz)') : '-';

            const canConnect = (state === 'disconnected' || state === 'error');
            const canDisconnect = !canConnect;
            const canGoOnline = canConnect; // Pode tentar ir online se desconectado/erro
            const canGoOffline = canDisconnect && state !== 'reconnecting'; // Pode ir offline se conectado/autenticado

            connectBtn.disabled = !canConnect;
            disconnectBtn.disabled = !canDisconnect;
            goOfflineBtn.disabled = !canGoOffline;
            goOnlineBtn.disabled = !canGoOnline;

            // Habilita operações de dados apenas se autenticado
            const allowDataOps = isAuth;
            dataOpsDiv.style.display = allowDataOps ? 'block' : 'none';
            listenerOpsDiv.style.display = allowDataOps ? 'block' : 'none';
        }

        // --- Event Handlers da Biblioteca ---
        fireSyncClient.on('state_changed', (newState) => {
            log(`>>> Evento: state_changed -> ${newState}`);
            updateUI();
        });
        fireSyncClient.on('error', (error) => {
            log(`>>> Evento: error -> ${error.message}`);
            updateUI(); // Atualiza UI para refletir estado de erro, se aplicável
        });
        fireSyncClient.on('disconnected', (details) => {
            log(`>>> Evento: disconnected -> Code: ${details.code}, Clean: ${details.wasClean}, UserReq: ${details.requestedByUser}`);
            updateUI();
            stopListener(); // Para listener ao desconectar
        });
        fireSyncClient.on('authenticated', () => {
             log(`>>> Evento: authenticated`);
             // O state_changed já chama updateUI, mas podemos fazer algo extra aqui se necessário
        });
         fireSyncClient.on('connecting', () => log(`>>> Evento: connecting`));
         fireSyncClient.on('connected', () => log(`>>> Evento: connected (WebSocket Aberto)`));
         fireSyncClient.on('reconnecting', () => log(`>>> Evento: reconnecting`));


        // --- Event Handlers dos Botões ---
        connectBtn.addEventListener('click', () => {
            const token = jwtInput.value.trim();
            if (!token) { alert("Por favor, insira um token JWT."); return; }
            log("Configurando token...");
            fireSyncClient.setAuthToken(token);
            log("Conectando...");
            updateUI(); // Atualiza para estado 'connecting'

            fireSyncClient.connect()
                .then(() => { log("Conexão e Autenticação OK!"); /* updateUI será chamado por state_changed */ })
                .catch(err => { log(`Erro ao conectar: ${err.message}`); /* updateUI será chamado por state_changed */ alert(`Falha: ${err.message}`); });
        });

        disconnectBtn.addEventListener('click', () => { log("Solicitando desconexão..."); fireSyncClient.disconnect(); updateUI(); });
        goOfflineBtn.addEventListener('click', () => { log("Solicitando ficar offline..."); fireSyncClient.goOffline(); updateUI(); });
        goOnlineBtn.addEventListener('click', () => { log("Solicitando ficar online..."); fireSyncClient.goOnline().catch(err => { log(`Erro ao tentar ficar online: ${err.message}`); alert(`Falha: ${err.message}`); updateUI(); }); updateUI(); });

        setBtn.addEventListener('click', () => handleDataAction('set'));
        updateBtn.addEventListener('click', () => handleDataAction('update'));
        getBtn.addEventListener('click', () => handleDataAction('get'));
        removeBtn.addEventListener('click', () => handleDataAction('remove'));
        pushBtn.addEventListener('click', () => handleDataAction('pushWithValue'));
        pushRefBtn.addEventListener('click', () => handleDataAction('pushRefOnly'));
        toggleListenerBtn.addEventListener('click', startStopListener);


        // --- Funções de Ação de Dados ---
        function handleDataAction(actionType) {
            const path = pathInput.value.trim();
            const valueStr = valueInput.value.trim();
            let value;

            if (!path && actionType !== 'pushRefOnly' && actionType !== 'pushWithValue') {
                alert("Path relativo não pode ser vazio para esta ação."); return;
            }

            // Parseia valor se necessário para set/update/push
            if (['set', 'update', 'pushWithValue'].includes(actionType)) {
                 if (!valueStr) { alert("Valor JSON não pode ser vazio para esta ação."); return; }
                 try { value = JSON.parse(valueStr); }
                 catch (e) { alert(`Valor JSON inválido: ${e.message}`); return; }
            }

            // Atualiza o timestamp se o valor for um objeto e tiver a chave "timestamp"
             if (typeof value === 'object' && value !== null && value.hasOwnProperty('timestamp')) {
                 value.timestamp = Date.now();
                 valueInput.value = JSON.stringify(value); // Atualiza textarea
                 log("Timestamp atualizado no payload.");
            }

            log(`Executando ação: ${actionType} em '${path || '(raiz do push)'}'...`);
            const targetRef = fireSyncClient.ref(path); // Cria referência

            let promise;
            switch (actionType) {
                case 'set':
                    promise = targetRef.set(value);
                    break;
                case 'update':
                    promise = targetRef.update(value); // 'value' deve ser um objeto
                    break;
                case 'get':
                    promise = targetRef.get();
                    break;
                case 'remove':
                    promise = targetRef.remove();
                    break;
                case 'pushWithValue':
                    promise = fireSyncClient.ref(path).push(value); // Push é na ref pai
                    break;
                case 'pushRefOnly':
                     const newRef = fireSyncClient.ref(path).push(); // Push é na ref pai
                     log(`Push (só ref) gerou path relativo: ${newRef.relativePath}, chave: ${newRef.key}`);
                     // Seleciona o novo path para facilitar o próximo Set/Get
                     pathInput.value = newRef.relativePath;
                     promise = Promise.resolve(newRef); // Resolve imediatamente com a ref
                    break;
                default:
                    log("Ação desconhecida.");
                    promise = Promise.reject(new Error("Ação desconhecida"));
            }

            promise.then(result => {
                log(`Sucesso na ação ${actionType} para '${path || '(raiz do push)'}'.`);
                if (actionType === 'get') {
                    const snapshot = result; // 'result' é o DataSnapshot para 'get'
                    const resultText = `Existe: ${snapshot.exists()}\nChave: ${snapshot.key}\nValor: ${JSON.stringify(snapshot.val(), null, 2)}`;
                    getLastResultPre.textContent = resultText;
                    log(`Resultado Get:\n${resultText}`);
                }
                 if (actionType === 'pushWithValue') {
                     const newRef = result; // 'result' é a DatabaseReference para push com valor
                     log(`Push com valor completo. Nova ref path: ${newRef.path}`);
                     // Seleciona o novo path para facilitar
                     pathInput.value = newRef.relativePath;
                 }

            }).catch(error => {
                log(`Erro na ação ${actionType} para '${path || '(raiz do push)'}': ${error.message}`);
                if (actionType === 'get') {
                    getLastResultPre.textContent = `Erro: ${error.message}`;
                }
                alert(`Erro ${actionType}: ${error.message}`);
            });
        }

        // --- Funções do Listener ---
        function startStopListener() {
            if (currentListenerUnsubscribe) {
                // Para o listener existente
                log(`Parando listener em '${currentListenerPath}'...`);
                currentListenerUnsubscribe();
                currentListenerUnsubscribe = null;
                currentListenerPath = null;
                onValueDataPre.textContent = "(Listener inativo)";
                toggleListenerBtn.textContent = "Iniciar Listener";
                listenerPathInput.disabled = false;
            } else {
                // Inicia novo listener
                const path = listenerPathInput.value.trim();
                if (!path) { alert("Path do listener não pode ser vazio."); return; }
                log(`Iniciando listener onValue para '${path}'...`);
                try {
                    const listenerRef = fireSyncClient.ref(path);
                    currentListenerUnsubscribe = listenerRef.onValue(
                        (snapshot) => {
                            const dataText = `[${new Date().toLocaleTimeString()}] Path: ${snapshot.ref.path}\nExiste: ${snapshot.exists()}\nValor: ${JSON.stringify(snapshot.val(), null, 2)}`;
                            onValueDataPre.textContent = dataText;
                            log(`Listener recebeu dados para '${path}'.`);
                        },
                        (error) => {
                            log(`Erro no listener para '${path}': ${error.message}`);
                            onValueDataPre.textContent = `Erro no listener: ${error.message}`;
                            // Limpa para permitir tentar novamente
                            currentListenerUnsubscribe = null;
                             currentListenerPath = null;
                            toggleListenerBtn.textContent = "Iniciar Listener";
                             listenerPathInput.disabled = false;
                        }
                    );
                    currentListenerPath = path; // Guarda o path que estamos escutando
                    toggleListenerBtn.textContent = `Parar Listener (${path})`;
                    listenerPathInput.disabled = true; // Desabilita input enquanto escuta
                    onValueDataPre.textContent = "(Aguardando dados...)";
                } catch (e) {
                     log(`Erro ao iniciar listener para '${path}': ${e.message}`);
                     alert(`Erro ao iniciar listener: ${e.message}`);
                }
            }
        }

        // --- Inicialização da UI ---
        updateUI(); // Define estado inicial dos botões

    </script>

</body>
</html>

Como Usar Este Exemplo:

  1. Salve: Salve o código HTML acima como index.html (ou outro nome).

  2. Biblioteca: Certifique-se de que o arquivo fsc.js esteja no caminho correto referenciado na tag <script src=https://cdn.firesync.app/clients/fsc.js"></script>.

  3. Testar:

    • Cole um TOKEN válido na caixa de texto.

    • Clique em "Conectar". Observe os logs e o status.

    • Use os botões de operação de dados (Set, Get, Update, Remove, Push) para interagir com os caminhos. O campo Value aceita JSON (lembre-se de usar aspas duplas para strings e chaves dentro do JSON).

    • Use a seção "Listener em Tempo Real" para iniciar/parar um listener onValue em um caminho específico e observar as atualizações.

    • Teste os botões Ficar Offline e Ficar Online para ver o controle manual e a reconexão automática em ação (se você derrubar o servidor e voltar, por exemplo, após clicar em Ficar Online ou se estava online).

Este exemplo deve dar uma boa visão geral de como utilizar as funcionalidades

AnteriorTratamento de ErrosPróximoCliente NodeJS

Atualizado há 1 mês