Firebase:在成功回调中使用新创建的密钥

时间:2015-11-06 07:57:12

标签: javascript asynchronous callback firebase promise

当推送事件发生时,它将返回一个新密钥。

例如来自Docs

// Generate a reference to a new location and add some data using push()
var newPostRef = postsRef.push();

// Get the unique ID generated by push()
var postID = newPostRef.key();

我想做的事情:

现在我想直接使用此密钥,以便在数据库的其他部分进行更改。

但由于JavaScript的异步特性,我已经被绊倒了。

我尝试过成功回调:

var newMessageIDRef =  firebaseMessagesRef.push({
  authorName: 'Nick',
  text:"Hello!"
},printKey(newMessageIDRef));

var printKey = function(newMessageIDRef) {
  console.log(newMessageIDRef);//undefined
}

(我假设在设置newMessageIDRef之前调用printKey

我已尝试使用"然后":

var newMessageIDRef =  firebaseConvosRef.push({
    authorName: 'Nick',
    text:"Hello!",
}).then(printKey(newMessageIDRef));

var printKey = function(newMessageIDRef) {
  console.log(newMessageIDRef);//undefined
}

(我假设parens导致printKey被立即执行,这让我想知道我如何添加params但不会导致早期执行)

问题:

是否有一些常规方法可以处理如此常见的内容,或者是使用Promise并使用resolve处理密钥的最佳解决方案?

更新(尽管尚未回答):

以下是有效但但没有意义。

var printKey = function(newMessageIDRef) {
    console.log(newMessageIDRef);//undefined
}

var newMessageIDRef =  firebaseConvosRef.push({
    authorName: 'Nick',
    text:"Hello!",
});
printKey(newMessageIDRef)

我认为在调用newMessageIDRef时不一定会返回printKey

3 个答案:

答案 0 :(得分:1)

根据the documentation.push()的工作原理如下:

  • 返回“生成位置的Firebase参考”
  • 作为第二个arg接受一个回调函数,“当指定的值与Firebase服务器同步时将调用”。回调接受一个参数,如果发生错误则为错误对象,否则为null

因此,为了在回调中使用返回的引用,必须对其进行分配,然后通过回调将其作为外部变量进行访问。

var newMessageIDRef = firebaseMessagesRef.push({
    authorName: 'Nick',
    text:"Hello!"
}, printKey);

var printKey = function(err) {
    if(!err) {
        console.log(newMessageIDRef);
    }
}

或者,您可以使用(至少)两个Firebase promisifier中的一个进行宣传,这两个方面看起来都不错,但目前在文档中缺少其明确的.push()的具体示例:

<强> Fireproof

这是一个有根据的猜测,它是如何工作的:

var fireproofMessagesRef = new Fireproof(firebaseMessagesRef);

fireproofMessagesRef.push({
    authorName: 'Nick',
    text:"Hello!"
}).then(successHandler, errorHandler);

function successHandler(childIDRef) {
    console.log(childIDRef);
}
function errorHandler(err) {
    console.error(err);
}

<强> Firebase-promisified

再次,一个有根据的猜测:

// having promisified Firebase.
firebaseMessagesRef.promisePush({
    authorName: 'Nick',
    text:"Hello!"
}).then(successHandler, errorHandler);

function successHandler(childIDRef) {
    console.log(childIDRef);
}
function errorHandler(err) {
    console.error(err);
}

我在这两种情况下的主要不确定性是childIdRef是否在成功处理程序中显示为一个参数,这看似合理但我找不到确认。

答案 1 :(得分:1)

Firebase JavaScript SDK不会公开任何承诺,因此没有then()。它取而代之的是基于回调。

除此之外,我不完全确定你想要完成什么。所以我只是给出一些常见的片段,希望其中一个有所帮助。

Firebase的push()操作是纯粹的客户端操作。它不执行到服务器的往返,但在客户端上生成统计上唯一的ID。

现在让我们假设您要创建一个新帖子(在/posts/$postid下)将该新帖子的链接添加到数据库的另一个位置(例如/users/$uid/posts/$postid ):

// Generate a reference to a new location and add some data using push()
var newPostRef = postsRef.push();

// Get the unique ID generated by push()
var postID = newPostRef.key();

// ref is a reference to the root, uid is the id of the current user
var userRef = ref.child('users').child(uid);

// Write the post to Firebase
newPostRef.set({ title: 'Firebase: Using the newly created key...', uid: uid }, function(newRef) {
    userRef.child('posts').child(postID).set(true);
});

你会注意到我没有在回调中使用newRef。因为我已经知道postID是什么。

上述方法将对Firebase执行两次写操作:

  1. 实际帖子
  2. 指向用户个人资料中帖子的链接
  3. 自Firebase 2.4(适用于JavaScript,适用于Android和iOS的2.3)以来,可以将这两种写操作作为单个操作执行。这再次利用了我们可以“预先计算”后ID作为客户端push()操作的事实:

    var ref = new Firebase('https://your-app.firebaseio.com');
    var postsRef = ref.child('posts');
    
    // Get a unique ID generated by push()
    var postID = postsRef.push().key();
    
    // Create a single object, where we'll put all updates
    var updates = {};
    
    // We'll put the post into /posts/$postId
    updates['/posts/'+postID] = { title: 'Firebase: Using the newly created key...', uid: uid };
    
    // Put the postId under /users/$uid/posts/$postId
    updates['/users/'+uid+'/posts/'+postID] = true;
    
    // Now write to both locations in one "big" swoop:    
    ref.update(updates);
    

    了解更多相关信息:

答案 2 :(得分:0)

pushthen都需要回调函数作为参数。你必须自己传递printKey,而不是调用它(用什么?!)并传递结果。它应该是

function printKey(newMessageIDRef) {
  console.log(newMessageIDRef);
}
firebaseConvosRef.push({
    authorName: 'Nick',
    text:"Hello!",
}).then(printKey);
//      ^^^^^^^^