Permiso de Firebase denegado

123

Soy relativamente nuevo en la codificación y estoy teniendo problemas.

Tengo este código para enviar datos a 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: ""
});

Sin embargo, sigo recibiendo el error:

ADVERTENCIA DE INCENDIO: establecido en / users / (GoogleID) falló: permission_denied 2016-05-23 22: 52: 42.707 firebase.js: 227 No capturado (en promesa) Error: PERMISSION_DENIED: Permiso denegado (...)

Cuando trato de buscar esto, habla de las reglas para Firebase, que parece estar en un idioma que aún no he aprendido (o simplemente me está pasando por la cabeza). ¿Alguien puede explicar qué está causando el problema? Pensé que era porque estaba pidiendo que almacenara el correo electrónico y el nombre para mostrar del usuario y simplemente no se me permitía hacer esto, pero cuando los saqué, todavía tenía el mismo problema. ¿Hay alguna manera de evitar este error sin establecer las reglas, o las reglas son algo que puedo aprender a escribir en un día, o simplemente estoy fuera de mi alcance?

¡Gracias por cualquier ayuda!

Robert Prine
fuente

Respuestas:

250

Por defecto, la base de datos en un proyecto en Firebase Console solo es legible / escribible por usuarios administrativos (por ejemplo, en Cloud Functions, o procesos que usan un Admin SDK). Los usuarios de los SDK normales del lado del cliente no pueden acceder a la base de datos, a menos que cambie las reglas de seguridad del lado del servidor.


Puede cambiar las reglas para que la base de datos solo sea legible / escribible por usuarios autenticados:

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

Consulta el inicio rápido para conocer las reglas de seguridad de la base de datos de Firebase .

Pero como no está iniciando sesión con el usuario desde su código, la base de datos le niega el acceso a los datos. Para resolverlo, deberá permitir el acceso no autenticado a su base de datos o iniciar sesión en el usuario antes de acceder a la base de datos.

Permitir acceso no autenticado a su base de datos

La solución más simple por el momento (hasta que se actualice el tutorial) es ir al panel de la base de datos en la consola para su proyecto, seleccionar la pestaña Reglas y reemplazar el contenido con estas reglas:

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

Esto hace que su nueva base de datos sea legible y escribible por cualquiera que conozca la URL de la base de datos. Asegúrese de asegurar su base de datos nuevamente antes de comenzar la producción, de lo contrario es probable que alguien comience a abusar de ella.

Inicie sesión en el usuario antes de acceder a la base de datos.

Para obtener una solución (un poco) más lenta, pero más segura, llame a uno de los signIn...métodos de autenticación de Firebase para asegurarse de que el usuario haya iniciado sesión antes de acceder a la base de datos. La forma más sencilla de hacerlo es mediante la autenticación anónima :

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

Y luego adjunte sus oyentes cuando se detecte el inicio de sesión

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
fuente
1
Gracias: usé la solución insegura y cité su respuesta en una respuesta a una pregunta similar para avanzar en los problemas de permisos anteriores de Firebase en este tutorial de Ember . Pero, ¿dónde agregamos el código de autenticación anónimo (seguro)?
Dave Everitt
2
Dios mío, ahí va una hora. Tenía esto allí, pero los valores eran FALSOS ... Simplemente lo pasé por alto. Los cambié a VERDADERO y bam, la aplicación funciona como pensarías ...
Andy
OMG, yo también, no podía entender por qué estaban fallando en los permisos cuando ambos ya estaban configurados en falso (hasta que leí tu comentario). duh, noob error., ambos deben ser ciertos cuando lo estás haciendo abierto al público (lecturas). Gracias por señalar tu propio error, me ayudaste a resolverlo. Para el registro, cambié mi regla a esto: ".read": verdadero y luego comenzó a funcionar.
contractorwolf
@Andy Gracias hombre, lo mismo para mí y ver tu comentario acaba de resolver mi problema;)
Mahmudul Hasan Sohag
86

Estaba enfrentando un problema similar y descubrí que este error se debía a reglas incorrectas establecidas para las operaciones de lectura / escritura para la base de datos en tiempo real. Por defecto, google firebase actualmente carga la tienda en la nube, no la base de datos en tiempo real. Necesitamos cambiar al tiempo real y aplicar las reglas correctas.

ingrese la descripción de la imagen aquí

Como podemos ver, dice que Cloud Firestore no es una base de datos en tiempo real, una vez que se cambia a la base de datos correcta, aplique las siguientes reglas:

{
   "rules": {
       ".read": true,
       ".write": true
     }
 }
solo sé raro
fuente
3
Maldita interfaz de usuario! Pasé todo el día, descubriendo por qué tengo reglas diferentes ... Ah ... Fue para "Cloud Firestore" ... ¡Gracias!
Alexey Volodko
43

Vaya a la opción "Base de datos" que mencionó.

  1. Allí, en el encabezado azul, encontrarás un menú desplegable que dice Cloud Firestore Beta
  2. Cámbielo a "Base de datos en tiempo real"
  3. Vaya a Reglas y establezca .write .read ambos en true

Copiado de aquí .

Ahmed Adewale
fuente
11

Ir a la base de datos, al lado del título hay 2 opciones:

Cloud Firestore, base de datos en tiempo real

Seleccione la base de datos en tiempo real y vaya a las reglas

cambia las reglas a verdadero.

Esto resolvió mi problema.

Jaywant Narwade
fuente
4
  1. Abra firebase, seleccione la base de datos en el lado izquierdo.
  2. Ahora en el lado derecho, seleccione [Base de datos en tiempo real] en el menú desplegable y cambie las reglas a: {"reglas": {".read": verdadero, ".write": verdadero}}

funciona..!!

Anindya Sankar Dasgupta
fuente
55
Esto ya se ha dicho en la otra respuesta. Además, cuando sugieras esto, ¡asegúrate de agregar una advertencia porque no se guarda!
André Kool
4

OK, ¡pero no quieres abrir toda la base de datos en tiempo real! Necesitas algo como esto.

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

o

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

Otra solución es crear o iniciar sesión automáticamente en el usuario si ya tiene las credenciales a mano. Así es como lo hago usando Plain JS.

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
fuente
Esto es realmente malo para la seguridad.
ASH