Cloud Functions を書いてると、 event.data.ref
, event.data.parent.ref
, event.data.adminRef
とか色々出てきてややこしいので整理した。
公式の例 で、 /messages/{pushId}/original
の変更を検知したケースで考えてみる。
exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
.onWrite(event => {
const original = event.data.val();
const uppercase = original.toUpperCase();
return event.data.ref.parent.child('uppercase').set(uppercase);
})
event.data.ref
// read
event.data.ref.once('value').then((snapshot) => {
console.log('ref:', snapshot.val());
// -> ref: messsage
})
// write
event.data.ref.set('newValue')
// update
event.data.ref.parent.update({'original': 'newValue'})
event.data.ref
で取れるのは event.data.val()
と同じもの。
write はそのまま ref.set('newValue')
でいけるのだが、 ref.update('newValue')
とするとエラーが帰ってくるので ref.parent.update({key: value})
とする必要があり、ややこしい。
エラーはこういうのが出る: Error: Firebase.update failed: First argument must be an object containing the children to replace.
* 参考: Interface: DeltaSnapshot#ref
event.data.adminRef
// read
event.data.adminRef.once('value').then((snapshot) => {
console.log('ref:', snapshot.val())
// -> adminRef: message
})
// write
event.data.adminRef.set('newValue')
// update
event.data.adminRef.parent.update({'original': 'newValue'})
adminRef は基本的に ref と同じものだが、権限が強いという違いがある。
権限を絞っていると ref だと取得できないデータもあるが、 adminRef だと取得できる。基本的に ref を使った方が事故を防げそう。
* 参考: Interface: DeltaSnapshot#adminRef
event.data.ref.parent
// read
event.data.ref.parent.once('value').then((snapshot) => {
console.log('parent:', snapshot.val())
// -> parent: parent: { original: 'message' }
})
// write
event.data.ref.parent.child('original').set('newValue')
// update
event.data.ref.parent.update({'original': 'newValue'})
/messages/{pushId}/original
の1つ上の階層、つまり messages/{pushId}
の Object を取得する。
write の場合は parent.child('key').set('hoge')
のように、どの子要素に書き込むのか指定する必要がある。
update は ref の時と同じ。
おわり
update のところがややこしい。
整理するとそんな難しくなくて当然なんだけど、開発中はどれがどうなってるのか混乱してしまった。