1

J'ai essayé d'ajouter des règles à ma base de données Firebase pendant quelques jours, mais une erreur persiste et je ne trouve pas ce qui ne va pas.Firebase multi-path update - Autorisation refusée

Il est l'erreur:

Firebase AVERTISSEMENT: mise à jour à/a échoué: PERMISSION_DENIED

PERMISSION_DENIED: Autorisation refusée

J'ai cherché des solutions et a trouvé un certain poste lié (Permission denied error during multiple update on Firebase) . Il semble que l'erreur affichée ne soit pas correcte. Je pensais que je l'avais parce que je n'avais aucun droit défini sur mon chemin racine ('/'), mais selon ce post, ce n'est pas un problème.

J'ai essayé de définir mes 3 règles 'write' sur 'true' et cela fonctionne, donc je suppose que le problème doit être dans mes règles.

Voir ci-dessous mon code.

Service angulaire:

let event = { 
    "title": "Title" 
    "uid": "FZON4aEQgKNnRlHqMH7ZwynhTtp1" 
} 

let uid = this.authService.fbUser.uid; 
let eventId = this.db.list('eventsData').push(undefined).key; 

let updateObject = {}; 
updateObject[`eventData/${eventId}`] = event; 
updateObject[`userEvents/${uid}/${eventId}`] = true; 
updateObject[`eventGuests/${eventId}/${uid}`]= { 
    attendance: 2 // and some other data 
}; 

return this.db.object('/').update(updateObject); 

La hiérarchie des données:

{ 
    "eventData" : { 
    "-KptoNEw3MKRfacLnqa6" : { //Some data equal to 'event' object in above Angular service } 
    }, 
    "eventGuests" : { 
    "-KptoNEw3MKRfacLnqa6" : { 
     "FZON4aEQgKNnRlHqMH7ZwynhTtp1" : { // Some data } 
    } 
    }, 
    "userEvents" : { 
    "FZON4aEQgKNnRlHqMH7ZwynhTtp1" : { 
     "-KptoNEw3MKRfacLnqa6" : true 
    } 
    }, 
    "users" : { 
    "FZON4aEQgKNnRlHqMH7ZwynhTtp1" : { //Some data } 
    } 
} 

règles Firebase: (j'ai enlevé '.Lire' droits pour rendre le code plus propre car ils ne sont pas une partie du problème)

{ 
    "rules": { 
    "eventData": { 
     "$eventId": { 
     // Event owner can update data 
     // OLD > ".write": "auth.uid == data.child('uid').val()" 
     // NEW 
     ".write": "(newData.child('uid').val() == auth.uid) && (!data.exists() || data.child('uid').val() == auth.uid)" 
     } 
    }, 
    "eventGuests": { 
     "$eventId": { 
     "$uid": { 
      // Event owner can add someone to the event 
      // Actual user can modify his attendance 
      ".write": "(auth.uid == root.child('eventData').child($eventId).child('uid').val()) || (auth.uid == $uid && data.exists() && newData.exists())" 
     } 
     } 
    }, 
    "userEvents": { 
     "$uid": { 
     "$eventId": { 
      // Event owner can add his event to someone's list 
      ".write": "auth.uid == root.child('eventData').child($eventId).child('uid').val()" 
     } 
     } 
    } 
    } 
} 

Merci d'avoir regardé!

MISE À JOUR:

Depuis la correction d'un bug par Frank, j'ai couru quelques nouveaux tests.

J'ai fait la mise à jour non multi-chemin, mais un par un, en commentant ceux que je ne voulais pas exécuter. En outre, j'ai essayé avec des valeurs statiques.

let updateObject = {}; 
updateObject[`eventData/-Kpu9op4_s3jCetav6xn`]= { 
    "title": "Title" 
    "uid": "FZON4aEQgKNnRlHqMH7ZwynhTtp1" 
}; 
return this.db.object('/').update(updateObject); 

Puis:

let updateObject = {}; 
updateObject[`userEvents/${uid}/-Kpu9op4_s3jCetav6xn`]= true; 
return this.db.object('/').update(updateObject); 

Et:

let updateObject = {}; 
updateObject[`eventGuests/-Kpu9op4_s3jCetav6xn/${this.authService.fbUser.uid}`]= { 
    attendance: 2 // and some other data 
}; 
return this.db.object('/').update(updateObject); 

Les trois d'entre eux travaillaient. Mais quand j'exécute le code en utilisant multi-path (3 en même temps), j'obtiens toujours l'erreur d'autorisation refusée.

+0

Pourquoi avez-vous des parenthèses de tableau autour de chaque enfant: '' ['eventData/$ {key}'] ''? –

+0

Notez également que nous n'avons aucune idée de ce qu'est 'event'. Assurez-vous que votre question contient le [code minimal et complet requis pour reproduire le problème] (http://stackoverflow.com/help/mcve). Un moyen facile d'assurer cela est d'utiliser des valeurs codées en dur pour tout. –

+0

A propos des parenthèses, il s'agit d'un reste de quand j'ai utilisé un objet externe (myUpdateObject ['eventData/$ {key}'] = myData). Laissez-moi mettre à jour tout ça! –

Répondre

0

J'ai couru un dernier test pour confirmer ce que je pensais.

Voici comment mes règles avaient l'air quand il a échoué plus tôt:

eventGuests: Indiquez si l'utilisateur actuel est propriétaire de l'événement OU si l'utilisateur actuel est celui d'être modifié

». écrire ":" (auth.uid == root.child ('eventData'). child ($ eventId) .child ('uid') .val()) || (auth.uid == $ uid & & données. exists() & & newData.exists()) "

userEvents: Indiquez si l'utilisateur actuel est propriétaire de l'événement

".write":. « Auth.uid == root.child ('EventData') enfant (eventId de $) .child ('uid') .val() »

maintenant, si j'utilise les éléments suivants à la place, qui fonctionne:

(root.child ('EventData'!) enfant (eventId de $) les .exists (.) || auth.uid == root.child ('EventData'). Enfant (eventId de $) .child ('uid'). Val())

Il semble que les données de la transaction ne sont pas accessibles avant la fin de la transaction.

En appelant ce qui suit dans cet ordre exact ...

let updateObject = {}; 
updateObject[`eventData/${eventId}`] = event; 
updateObject[`userEvents/${uid}/${eventId}`] = true; 
updateObject[`eventGuests/${eventId}/${uid}`]= { 
    attendance: 2 // and some other data 
}; 

... Je me attendais EventData être persisté et être accessible à userEvents et eventGuests. Et puis, si une erreur se produisait, le système aurait été annulé. Mais on dirait que ça ne marche pas comme ça. Est-ce que quelqu'un peut confirmer que les données transmises dans une transaction ne sont pas accessibles tant que la transaction n'est pas validée?

1

Une première erreur semble en /eventData/$event:

".write": "auth.uid == data.child('uid').val()" 

Depuis data est les données existantes à l'endroit, je suis sûr que cette règle échouera quand il n'y a pas de données existantes.

Plus probable que vous voulez:

(newData.child('uid').val() == auth.uid) && 
(!data.exists() || data.child('uid').val() == auth.uid) 
+0

Vous avez raison. Cela faisait partie du problème, mais j'ai toujours la même erreur à la fin. Je vais mettre à jour ma réponse avec les quelques nouveaux tests que j'ai menés et les résultats. –