javascript - 如何使用 AngularJS 从 Firebase 读取对象

标签 javascript angularjs firebase angularfire

我正在开发我的应用程序,其中一项功能是应用程序内的消息传递。我所做的是开发了“发送消息”窗口,用户可以在其中向其他用户发送消息。其背后的逻辑如下:
1. 用户A发送消息给用户B。
2. Firebase 在“消息传递”中创建以下节点:
“消息”->“用户 A”->“用户 B”->“日期和时间”->“用户 A:消息”
“消息”->“用户 B”->“用户 A”->“日期和时间”->“用户 A:消息”

这是我用于发送消息的代码:

  sendMsg: function(receiver, content) {
    var user = Auth.getUser();
    var sender = user.facebook.id;
    var receiverId = receiver;
    var receiverRef = $firebase(XXX.firebase.child("Messaging").child(receiverId).child(sender).child(Date()));
    var senderRef = $firebase(XXX.firebase.child("Messaging").child(sender).child(receiverId).child(Date()));
    receiverRef.$set(sender,content);
    senderRef.$set(sender,content);
  },

(imgur相册中的图1)

目前,我正在尝试从数据库中读取消息,并根据日期对它们进行排序。到目前为止,我所完成的是以对象的形式存储“Messaging/UserA/”的内容。该物体可以在我所附的图片中看到(图2)。

/image/Fl6BC.jpg

数据接收代码:

getMsgs: function () {
    var user = Auth.getUser();
    var userId = user.facebook.id;
    var messagesPath = new Firebase("https://xxx.firebaseio.com/Messaging/");
    var Messages = messagesPath.child(userId);
    Messages.on("value", function (snapshot) {
      var messagesObj = snapshot.val();
      return messagesObj;
    }, function (errorObject) {
      console.log("Error code: " + errorObject.code);
    });
  }

我的问题是:如何读取对象的消息?我想根据日期排序,获取消息并获取发送消息的用户的ID。

非常感谢!

最佳答案

当您阅读消息时,您似乎陷入了异步加载陷阱:

getMsgs: function () {
    var user = Auth.getUser();
    var userId = user.facebook.id;
    var messagesPath = new Firebase("https://xxx.firebaseio.com/Messaging/");
    var Messages = messagesPath.child(userId);
    Messages.on("value", function (snapshot) {
      var messagesObj = snapshot.val();
      return messagesObj;
    }, function (errorObject) {
      console.log("Error code: " + errorObject.code);
    });
  }

Messages.on("value" 回调中的 return 语句不会将该值返回给任何人。

如果我们将回调分成一个单独的函数,通常会更容易看到发生了什么:

onMessagesChanged(snapshot) {
    // when we get here, either the messages have initially loaded 
    // OR there has been a change in the messages
    console.log('Inside on-value listener');
    var messagesObj = snapshot.val();
    return messagesObj;
},
getMsgs: function () {
    var user = Auth.getUser();
    var userId = user.facebook.id;
    var messagesPath = new Firebase("https://xxx.firebaseio.com/Messaging/");
    var Messages = messagesPath.child(userId);
    console.log('Before adding on-value listener');
    Messages.on("value", onMessagesChanged);
    console.log('After adding on-value listener');
  }

如果您像这样运行代码片段,您将看到控制台记录:

Before adding on-value listener
After adding on-value listener
Inside on-value listener

这可能不是您所期望的,是由于 Firebase 必须从其服务器检索消息而导致的,这可能需要很长时间。浏览器不会让用户等待,而是继续执行代码,并在数据可用时调用所谓的回调函数。

对于 Firebase,每当用户更改或添加消息时,您的函数实际上可能会被调用多次。所以输出更有可能是:

Before adding on-value listener
After adding on-value listener
Inside on-value listener
Inside on-value listener
Inside on-value listener
...

由于回调函数是异步触发的,因此您无法从中将值返回到原始函数。解决此问题的最简单方法是在回调中执行屏幕更新。所以说你想记录消息,你会这样做:

onMessagesChanged(snapshot) {
    // when we get here, either the messages have initially loaded 
    // OR there has been a change in the messages
    console.log('Inside on-value listener');
    var i = 0;
    snapshot.forEach(function(messageSnapshot) {
        console.log((i++)+': '+messageSnapshot.val());
    });
},

请注意,无论您使用什么 API 访问 Firebase,此问题都是相同的。但不同的库以不同的方式处理它。例如:AngularFire 在 AngularJS 返回时通知您数据更改,从而使您免受许多此类复杂性的困扰。

另请参阅:Asynchronous access to an array in Firebase

关于javascript - 如何使用 AngularJS 从 Firebase 读取对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29100210/

相关文章:

javascript - 无法从后端到前端 Angular 选择选项获取文件列表?

android - 具有单个字符串值的失败的 BINDER 事务,RecycleView/Firebase

javascript - JSON 数组 : OK Locally but get "Undefined" values when run from Server

javascript - jQuery tmpl if 对象值 == 当前迭代值

javascript - Angular js - isDate() 将不起作用

javascript - AngularJS 在选择菜单中显示多个值?

java - 我正在制作一个壁纸应用程序。我被困在某个地方

firebase - 没有创建 Firebase App '[DEFAULT]' - 在 Flutter 和 Firebase 中调用 Firebase.initializeApp()

javascript - 如何使用函数重置一组标志的值(用作其参数的标志除外)?

javascript - Angular.js - ui-router 不注入(inject) View