Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Firebase:在成功回调中使用新创建的键_Javascript_Asynchronous_Callback_Firebase_Promise - Fatal编程技术网

Javascript Firebase:在成功回调中使用新创建的键

Javascript Firebase:在成功回调中使用新创建的键,javascript,asynchronous,callback,firebase,promise,Javascript,Asynchronous,Callback,Firebase,Promise,当推送事件发生时,它将返回一个新密钥 例如: 我想做什么: 现在我想在数据库的另一部分中直接使用此键进行更改。 但由于JavaScript的异步特性,我一直被绊倒 我尝试了成功回调: var newMessageIDRef = firebaseMessagesRef.push({ authorName: 'Nick', text:"Hello!" },printKey(newMessageIDRef)); var printKey = function(newMessageIDRef

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

例如:

我想做什么:

现在我想在数据库的另一部分中直接使用此键进行更改。

但由于JavaScript的异步特性,我一直被绊倒

我尝试了成功回调:

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

var printKey = function(newMessageIDRef) {
  console.log(newMessageIDRef);//undefined
}
(我假设在设置newMessageIDRef之前调用了
printKey

我试过使用“then”:

(我假设parens导致立即执行
printKey
,这让我想知道如何添加参数但不导致提前执行)

问题:

是否有一些常规方法来处理如此常见的事情,或者我的最佳解决方案是使用
承诺
并使用
解决
来处理密钥?

更新(尚未答复):

下面是工作,但它没有意义

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

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

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

推送
都需要回调函数作为参数。您必须传递
printKey
本身,而不是调用它(使用什么?!)并传递其结果。应该是

function printKey(newMessageIDRef) {
  console.log(newMessageIDRef);
}
firebaseConvosRef.push({
    authorName: 'Nick',
    text:"Hello!",
}).then(printKey);
//      ^^^^^^^^
根据,
.push()
的工作原理如下:

  • 返回“生成位置的Firebase引用”
  • 接受作为第二个参数的回调函数,该函数“将在指定值与Firebase服务器同步时调用”。回调函数接受一个参数,如果发生错误,则为error对象,否则为
    null
因此,为了在回调中使用返回的引用,它必须被分配,然后由回调作为外部变量访问

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

var printKey = function(err) {
    if(!err) {
        console.log(newMessageIDRef);
    }
}
或者,您可以使用(至少)两个Firebase Promisifier中的一个进行promisify,这两个Promisifier看起来都不错,但目前在文档中缺少其promisified
.push()
的具体示例:

这是一个关于它可能如何工作的有根据的猜测:

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);
}

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

// 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
是否在成功处理程序中显示为参数,这似乎是合理的,但我找不到确认。

Firebase JavaScript SDK没有公开任何承诺,因此没有
then()
。相反,它基于回调工作

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

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

现在,假设您想创建一篇新文章(在
/posts/$postid
下),并将指向该新文章的链接添加到数据库的另一个位置(例如
/users/$uid/posts/$postid
):

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

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

  • 实际职位
  • 指向用户配置文件中帖子的链接
  • 由于Firebase 2.4(对于JavaScript,对于Android和iOS,为2.3)可以作为单个操作执行这两种写入。这再次利用了这样一个事实,即我们可以“预计算”post 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);
    
    请在以下网站上阅读更多信息:

    • 这(上面是一个例子)

    为什么要记录一个字符串而不是变量?@Bergi编写代码片段只是个意外,感谢您指出这一点!事实上,push“是一个纯粹的客户端操作,它不会像@FrankvanPuffelen所说的那样执行往返”,这使得这个问题更有意义。在成功回调中未定义或使用“then”让我相信是异步问题导致了问题。现在唯一的问题是,在第一次写入操作失败的情况下,我们如何回滚第二次写入操作?或者扇出策略是否涵盖了其中一次写入失败的情况?我提供的第二个解决方案向Firebase服务器发送单个命令。所以不需要回滚。
    // having promisified Firebase.
    firebaseMessagesRef.promisePush({
        authorName: 'Nick',
        text:"Hello!"
    }).then(successHandler, errorHandler);
    
    function successHandler(childIDRef) {
        console.log(childIDRef);
    }
    function errorHandler(err) {
        console.error(err);
    }
    
    // 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);
    });
    
    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);