2013-03-31 9 views
5

Proseguendo da questa discussione, sulla HN: https://news.ycombinator.com/item?id=5462769Implementazione rimuovere Tweet e come/funzionalità upvote in Firebase

Leggendo il file di regole firefeed risposto un sacco di domande per me, tranne che per questi due:

  1. La modifica di un tweet esistente non è consentita (".write": "! Data.exists()"). Come puoi renderlo non modificabile, ma cancellabile dall'autore?
  2. Come gestiresti in modo sicuro il Miking/Non Bloccato o il Upvoting/Downvoting? scrivere se autenticato, convalidare per l'aumento/diminuzione di uno, se l'utente non ha modificato prima questo? Come funzionerebbe? Dovrebbe esserci un elenco di persone che lo hanno modificato? Sono solo molto curioso di questo specifico caso d'uso in quanto sembra abbastanza comune in molte app, ma mi sembra che sarebbe davvero complicato da implementare in Firebase?

risposta

8

1. Non modificabile ma cancellabile dall'autore

".write": "!data.exists() || (!newData.exists() && data.child('author') === auth.id)" 

2. Simpatia/upvoting

Sul client, utilizzare una transazione che consente di incrementare il valore in modo sicuro :

ref.transaction(function(currentValue) { 
    return (currentValue||0)+1; 
}, function(error) { 
    if(error) /* failed too many times */ 
    else /* it worked */ 
}); 

Sicurezza è al così semplice:

".validate": "newData.isNumber() && newData.val() === data.val()+1" 

2,5 Garantire Voti unici

Non sono sicuro di che cosa questo significa; i record non possono essere modificati e presumibilmente se potessero, solo l'autore sarebbe in grado di farlo; quindi non capisco veramente "modificato" in questo contesto: "se l'utente non ha modificato prima questo? Come funzionerebbe?"

Per garantire che i voti siano univoci, è sufficiente memorizzarli per ID utente. L'utente può rimuovere il proprio voto eliminando il record.

Si consiglia di archiviarli in un percorso separato rispetto alle scintille e mantenere comunque un semplice incremento (i messaggi che vengono votati su/giù) in quanto non si desidera recuperare l'intero elenco di votanti ciascuno ora vai a prendere la scintilla.

Le norme di sicurezza apparirebbe in questo modo:

"votes": { 
    "$spark_id": { 
     "$vote": { 
      ".read": "$vote === auth.id", 
      ".write": "$vote === auth.id", 
      // to allow downvoting in addition to up or delete, just add -1 here 
      ".validate": "newData.val() === 1 || newData.val() === null" 
     } 
    } 
} 

E ora aggiungere un controllo per la regola di convalida per l'incremento:

".validate": "!root.child('votes').child($spark_id).child(auth.id).exists() && newData.isNumber() && newData.val() === data.val()+1" 
+0

Grazie mille per la risposta, che la regola di scrittura è pura arte nei miei occhi e mi dispiace di non essere stata abbastanza chiara con il bit "modificato". L'upvoting, implementato nel modo in cui hai descritto, consentirebbe all'utente di postare un post all'infinito, mentre solitamente tale funzionalità è limitata a una sola volta, per utente. Quindi ero curioso, come lasceresti l'uptote solo una volta, non lascerai due volte l'upvote, ma rimuoverò il loro voto e downvote. Capisco, come avrei ottenuto questo in un database relazionale, solo curioso, qual è il modo migliore per farlo in firebase. – Kirill

+0

L'ho già implementato per la nostra versione beta; è più semplice di quanto pensi; lascia che ti aggiunga. – Kato

+0

Eccoti, fammi sapere se qualcosa non è chiaro. – Kato

0

Ora che le funzioni Firebase è stato rilasciato (in versione beta) per il pubblico in generale, sembra essere una buona opzione: https://firebase.googleblog.com/2017/03/introducing-cloud-functions-for-firebase.html

L'idea è di consentire a ciascun utente di aggiungere il proprio nome, per chiave, a un campo "upvoters" lezione per il tweet. Possono creare o cancellare la loro voce - ma ce ne può essere solo una, poiché è la chiave di accesso e la regola di sicurezza consente solo il controllo della loro unica chiave.

Quando viene trovato il "conteggio positivo", il client potrebbe ottenere l'elenco completo di upvoters e calcolare il numero. Invece, per motivi di prestazioni, creiamo una funzione Firebase che viene attivata ogni volta che viene aggiunta o rimossa una voce upvote.

Tutto ciò che fa è quindi aumentare o diminuire una proprietà "conteggio positivo" sul tweet. È lo stesso di prima, eccetto che creiamo una regola di sicurezza che consente solo alla funzione ospitata dal cloud di modificare questo campo. Pertanto, la modifica è sempre affidabile e sicura e rimuove la necessità per il client di ricevere l'elenco di upvoters solo per ottenere il conteggio upvote.