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

Firebase: Using the newly created key in the success callback

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

例如来自 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
}

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

我试过使用 "then":

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

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

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

问题:

是否有一些传统的方法来处理如此常见的事情,或者我最好的解决方案是使用 Promise 并使用 resolve 处理密钥?

更新(虽然还没有回答):

以下是可行的,但没有意义。

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

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

我认为 newMessageIDRef 不一定会在调用 printKey 时被 return 编辑。

pushthen 都期望回调 function 作为它们的参数。您将必须传递 printKey 本身,而不是调用它(用什么?!)并传递其结果。应该是

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

根据the documentation.push() 的工作方式如下:

  • returns "a Firebase reference for the generated location"
  • 接受作为第二个参数的回调函数"will be called when the specified value is synchronized to the Firebase servers"。回调接受一个参数,如果发生错误则为错误对象,否则 null.

因此,为了在回调中使用返回的引用,它必须被赋值,然后作为外部变量被回调访问。

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

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

或者,您可以使用(至少)两个 Firebase promifiers 之一进行 promisify,这两个看起来都不错,但目前在文档中缺少它们 promisified .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 是否作为参数出现在成功处理程序中,这似乎是明智的,但我找不到确认。

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

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

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

现在假设您要创建一个新的 post(在 /posts/$postid 下) 并且 添加一个 link 到那个新的 post 到数据库的另一个位置(比如 /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. 实际post
  2. 用户个人资料中的 link 到 post

从 Firebase 2.4(对于 JavaScript、2.3 对于 Android 和 iOS)开始,可以将两个写入作为一个操作执行。这再次利用了我们可以 "pre-calculate" 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);

阅读更多相关信息: