Swift
とFirebase
を使用して、ソーシャルネットワーキングアプリケーションImpetherでこのような機能を実装した方法について説明します。
upvotingとdownvotingは類似しているので、私はupvotingだけを説明します。
一般的な考え方は、カウンタが関連する画像データに対応するノードにupvotesカウンタを直接格納し、トランザクションの書き込みを使用してカウンタ値を更新してデータの不一致を避けることです。
例えば、あなたが$imageId
、特定の画像を識別するために使用される固有のIDであるパス/images/$imageId/
、で単一の画像データを格納すると仮定する - それは、iOS用Firebaseに含まれる機能childByAutoIdによって例えば生成することができます。そして、そのノードにおいて単一の光に対応するオブジェクトは、次のようになります。私たちが何をしたいか
$imageId: {
'url': 'http://static.example.com/images/$imageId.jpg',
'caption': 'Some caption',
'author_username': 'foobarbaz'
}
すると、このノードにupvoteカウンタを追加することで、それは次のようになります。
$imageId: {
'url': 'http://static.example.com/images/$imageId.jpg',
'caption': 'Some caption',
'author_username': 'foobarbaz',
'upvotes': 12,
}
あなたがいる場合には(おそらくユーザーがそれをアップロードしたときに)新しい画像を作成したら、達成したいことに応じて、アップカウントカウンタ値を0
またはその他の定数で初期化することができます。
特定のupvotesカウンタを更新する場合は、値の矛盾を避けるためにトランザクションを使用する必要があります(これは、複数のクライアントが同時にカウンタを更新する場合に発生する可能性があります)。
幸い、トランザクションを処理することはFirebase
に書き込み、Swift
は超簡単です:
func upvote(imageId: String,
success successBlock: (Int) -> Void,
error errorBlock:() -> Void) {
let ref = Firebase(url: "https://YOUR-FIREBASE-URL.firebaseio.com/images")
.childByAppendingPath(imageId)
.childByAppendingPath("upvotes")
ref.runTransactionBlock({
(currentData: FMutableData!) in
//value of the counter before an update
var value = currentData.value as? Int
//checking for nil data is very important when using
//transactional writes
if value == nil {
value = 0
}
//actual update
currentData.value = value! + 1
return FTransactionResult.successWithValue(currentData)
}, andCompletionBlock: {
error, commited, snap in
//if the transaction was commited, i.e. the data
//under snap variable has the value of the counter after
//updates are done
if commited {
let upvotes = snap.value as! Int
//call success callback function if you want
successBlock(upvotes)
} else {
//call error callback function if you want
errorBlock()
}
})
}
上記スニップは、ほぼ正確に、実際に私たちが生産に使用するコードです。私はそれがあなたを助けることを願っています:)
ありがとうございます!Firebase SDKのアップデートでは、FMutableDataはFIRMutableDataになり、FTransactionResultはFIRTransactionResultになります – PAD
これは非常に参考になりました。 –
ユーザーがすでに好きだった場合の解決策はありません。そしてそれは+ to - に変わるだけではありません。 userIDを保存し、現在のuserIDと比較する必要があります。これははるかに複雑です。 –