2015-11-06 61 views
0

发生推送事件时,它将返回一个新密钥。Firebase:在成功回调中使用新创建的密钥

例如从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叫回来。

+0

为什么你要记录一个字符串而不是变量? – Bergi

+0

@Bergi,这只是一个意外,使片段,感谢指出! –

回答

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是什么。

上述方法将执行两次写操作以火力地堡:

  1. 实际岗位
  2. 的链接后在用户的个人资料

由于火力地堡2.4(对JavaScript,2.3对于Android和iOS),可以将这两个写入作为单个操作进行。这再次利用的事实,我们可以“预先计算”的帖子-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); 

阅读更多关于这一点:

+0

像“@FrankvanPuffelen”所说的那样推“纯粹的客户端操作,不执行往返”这一事实使得这个问题变得更加有意义。在成功回调中获取未定义或使用“then”会导致我认为存在导致此问题的异步问题。 –

+0

现在唯一的问题是如何在第一次写入操作失败的情况下回退第二次写入操作? –

+0

或者扇出策略是否覆盖其中一个写入失败的情况? –

0

pushthen都预计回调函数作为它们的参数。你将不得不通过printKey本身,而不是调用它(以什么?!)并通过它的结果。它应该是

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

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

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

因此,为了在回调中使用返回的引用,它必须被分配,然后由回调作为外部var访问。

Fireproof

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

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

或者,你可以用的(至少)两个火力地堡promisifiers,这两者似乎不错,但目前缺乏自己的文档中promisified .push()的具体例之一promisify

这是一个有教育的猜测,它可能如何工作:

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是否显示为成功处理程序设置了一个param,这似乎合理,但我可以找不到确认。