Permissão de Firebase negada

123

Eu sou relativamente novo em codificação e estou tendo problemas.

Eu tenho esse código para enviar dados para o firebase

app.userid = app.user.uid

var userRef = app.dataInfo.child(app.users);

var useridRef = userRef.child(app.userid);

useridRef.set({
  locations: "",
  theme: "",
  colorScheme: "",
  food: ""
});

No entanto, continuo recebendo o erro:

AVISO DO FIREBASE: definido em / users / (GoogleID) falhou: permission_denied 23-05-2016 22: 52: 42.707 firebase.js: 227 Erro não detectado (por promessa): PERMISSION_DENIED: permissão negada (…)

Quando tento pesquisar, ele fala sobre regras para o Firebase, que parece estar em um idioma que ainda não aprendi (ou está passando por cima da minha cabeça). Alguém pode explicar o que está causando o problema? Eu pensei que estava pedindo para armazenar e-mail e nome de exibição do usuário e você simplesmente não tinha permissão para fazer isso, mas quando eu os tirei, ainda tinha o mesmo problema. Existe uma maneira de evitar esse erro sem definir as regras, ou as regras são algo que eu posso aprender a escrever em um dia ou estou apenas fora do meu alcance?

Obrigado por qualquer ajuda!

Robert Prine
fonte

Respostas:

250

Por padrão, o banco de dados em um projeto no Firebase Console é legível / gravável apenas por usuários administrativos (por exemplo, em Cloud Functions ou processos que usam um Admin SDK). Os usuários dos SDKs regulares do lado do cliente não podem acessar o banco de dados, a menos que você altere as regras de segurança do lado do servidor.


Você pode alterar as regras para que o banco de dados seja legível / gravável apenas por usuários autenticados:

{
  "rules": {
    ".read": "auth != null",
    ".write": "auth != null"
  }
}

Consulte o início rápido para obter as regras de segurança do banco de dados Firebase .

Mas como você não está conectando o usuário a partir do seu código, o banco de dados nega o acesso aos dados. Para resolver isso, você precisará permitir acesso não autenticado ao seu banco de dados ou entrar no usuário antes de acessar o banco de dados.

Permitir acesso não autenticado ao seu banco de dados

A solução mais simples para o momento (até a atualização do tutorial) é entrar no painel Banco de Dados no console do seu projeto, selecione a guia Regras e substitua o conteúdo por estas regras:

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

Isso torna seu novo banco de dados legível e gravável por qualquer pessoa que saiba o URL do banco de dados. Certifique-se de proteger seu banco de dados novamente antes de entrar em produção, caso contrário, é provável que alguém comece a abusar dele.

Entre no usuário antes de acessar o banco de dados

Para uma solução (um pouco) mais demorada, mas mais segura, chame um dos signIn...métodos de Autenticação do Firebase para garantir que o usuário esteja conectado antes de acessar o banco de dados. A maneira mais simples de fazer isso é usando autenticação anônima :

firebase.auth().signInAnonymously().catch(function(error) {
  // Handle Errors here.
  var errorCode = error.code;
  var errorMessage = error.message;
  // ...
});

E conecte seus ouvintes quando a entrada for detectada

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    // User is signed in.
    var isAnonymous = user.isAnonymous;
    var uid = user.uid;
    var userRef = app.dataInfo.child(app.users);

    var useridRef = userRef.child(app.userid);

    useridRef.set({
      locations: "",
      theme: "",
      colorScheme: "",
      food: ""
    });

  } else {
    // User is signed out.
    // ...
  }
  // ...
});
Frank van Puffelen
fonte
1
Obrigado - usou a correção insegura e citou sua resposta em uma resposta a uma pergunta semelhante para avançar os problemas de permissão do Firebase neste tutorial do Ember . Mas onde adicionamos o código de autenticação anônima (segura)?
Dave Everitt
2
OMG lá vai uma hora. Eu tinha isso lá, mas os valores eram FALSOS ... eu simplesmente esqueci. Mudou-los para TRUE e bam, app está funcionando como você pensaria ...
Andy
OMG, eu também, não conseguia descobrir por que eles estavam falhando nas permissões quando ambos já estavam configurados para false (até eu ler o seu comentário). duh, noob error., os dois devem ser verdadeiros quando você o abrir ao público (lê). Obrigado por apontar seu próprio erro, você me ajudou a descobrir. Para o registro, mudei minha regra para: ".read": true e, em seguida, começou a funcionar.
contractorwolf
@ Andy Obrigado cara, o mesmo para mim e ver o seu comentário acabou de resolver o meu problema;)
Mahmudul Hasan Sohag 15/01
86

Eu estava enfrentando um problema semelhante e descobri que esse erro era devido a regras incorretas definidas para operações de leitura / gravação para o banco de dados em tempo real. Por padrão, o google firebase atualmente carrega o armazenamento em nuvem e não o banco de dados em tempo real. Precisamos mudar para o tempo real e aplicar as regras corretas.

insira a descrição da imagem aqui

Como podemos ver, diz que o Firestore na nuvem não é o banco de dados em tempo real, uma vez alternado para o banco de dados correto, aplique as regras abaixo:

{
   "rules": {
       ".read": true,
       ".write": true
     }
 }
apenas seja estranho
fonte
3
UI maldita! Passei o dia inteiro, descobrindo por que tenho regras diferentes ... Ah ... Era para o "cloud firestore" ... Obrigado!
Alexey Volodko
43

Vá para a opção "Banco de dados" que você mencionou.

  1. Lá, no Blue Header, você encontrará uma lista suspensa que diz Cloud Firestore Beta
  2. Altere para "banco de dados em tempo real"
  3. Vá para Regras e defina .write .read ambos como true

Copiado daqui .

Ahmed Adewale
fonte
11

Vá para o banco de dados, ao lado do título, existem 2 opções:

Cloud Firestore, banco de dados em tempo real

Selecione banco de dados em tempo real e vá para regras

altere as regras para true.

Isso resolveu meu problema.

Jaywant Narwade
fonte
4
  1. Abra o firebase, selecione o banco de dados no lado esquerdo.
  2. Agora, no lado direito, selecione [Banco de dados em tempo real] no menu suspenso e altere as regras para: {"rules": {".read": true, ".write": true}}

funciona..!!

Anindya Sankar Dasgupta
fonte
5
Isso já foi dito na outra resposta. Além disso, quando você sugerir isso, adicione um aviso, pois isso não é salvo!
André Kool
4

OK, mas você não deseja abrir todo o banco de dados em tempo real! Você precisa de algo assim.

{
  /* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */
  "rules": {
    ".read": "auth.uid !=null",
    ".write": "auth.uid !=null"
  }
}

ou

{
  "rules": {
    "users": {
      "$uid": {
        ".write": "$uid === auth.uid"
      }
    }
  }
}
Ondřej Bauer
fonte
2

Outra solução é realmente criar ou efetuar login no usuário automaticamente se você já tiver as credenciais à mão. Aqui está como eu faço isso usando JS simples.

function loginToFirebase(callback)
{
    let email = '[email protected]';
    let password = 'xxxxxxxxxxxxxx';
    let config =
    {
        apiKey: "xxx",
        authDomain: "xxxxx.firebaseapp.com",
        projectId: "xxx-xxx",
        databaseURL: "https://xxx-xxx.firebaseio.com",
        storageBucket: "gs://xx-xx.appspot.com",
    };

    if (!firebase.apps.length)
    {
        firebase.initializeApp(config);
    }

    let database = firebase.database();
    let storage = firebase.storage();

    loginFirebaseUser(email, password, callback);
}

function loginFirebaseUser(email, password, callback)
{
    console.log('Logging in Firebase User');

    firebase.auth().signInWithEmailAndPassword(email, password)
        .then(function ()
        {
            if (callback)
            {
                callback();
            }
        })
        .catch(function(login_error)
        {
            let loginErrorCode = login_error.code;
            let loginErrorMessage = login_error.message;

            console.log(loginErrorCode);
            console.log(loginErrorMessage);

            if (loginErrorCode === 'auth/user-not-found')
            {
                createFirebaseUser(email, password, callback)
            }
        });
}

function createFirebaseUser(email, password, callback)
{
    console.log('Creating Firebase User');

    firebase.auth().createUserWithEmailAndPassword(email, password)
        .then(function ()
        {
            if (callback)
            {
                callback();
            }
        })
        .catch(function(create_error)
        {
            let createErrorCode = create_error.code;
            let createErrorMessage = create_error.message;

            console.log(createErrorCode);
            console.log(createErrorMessage);
        });
}
Parampal Pooni
fonte
Isso é realmente ruim em termos de segurança.
ASH