等待 firebase.auth 初始化完成后再执行另一个函数。

huangapple go评论145阅读模式
英文:

Wait for firebase.auth initialization before reading another function

问题

我对Firebase和JavaScript非常陌生。

我的项目: 构建一个私人消息应用程序。为此,我想在Firestore中定义一个子集合,用于私人消息,使用当前用户的ID和目标用户的ID。

以下是允许这样做的函数:

// 根据当前用户和他试图联系的用户生成正确的子集合
function dmCollection(toUid) {

  if (toUid === null) {
    // 如果没有定义目标用户,我们将其设置为下面的值
    toUid = 'fixed_value';
  };
  const idPair = [firebase.auth().currentUser.uid, toUid].join('_').sort();
  return firebase.firestore().collection('dms').doc(idPair).collection('messages');
};

我的问题: 我想使用firebase.auth().currentUser.uid属性,但似乎该函数不等待firebase.auth初始化。如何解决这个问题?

附加信息:
我有两个调用第一个函数(dmCollection)的函数:

// 检索DM
function messagesWith(uid) {
  return dmCollection(uid).orderBy('sent', 'desc').get();
};

// 发送DM
function sendDM(toUid, messageText) {
  return dmCollection(toUid).add({
    from: firebase.auth().currentUser.uid,
    text: messageText,
    sent: firebase.firestore.FieldValue.serverTimestamp(),
  });
};
英文:

I am very new with firebase and javascript.

My project: Build a private messaging app. To do that, I want to define a sub collection in firestore for private messaging using the current user id and the destination user id.

Here is the function that allows this:

// generate the right SubCollection depending on current User and the User he tries to reach
function dmCollection(toUid) {

  if (toUid === null) {
    // If no destination user is definer, we set it to the below value
    toUid = 'fixed_value';
  };
  const idPair = [firebase.auth().currentUser.uid, toUid].join('_').sort();
  return firebase.firestore().collection('dms').doc(idPair).collection('messages');
};

My problem: I want to use the firebase.auth().currentUser.uid attribute, but it looks like the function is not waiting for firebase.auth initialization. How can I fix this problem?

Additional information:
I have two functions that are calling the first one (dmCollection):


// retrieve DMs
function messagesWith(uid) {
  return dmCollection(uid).orderBy('sent', 'desc').get();
};


// send a DM
function sendDM(toUid, messageText) {
  return dmCollection(toUid).add({
    from: firebase.auth().currentUser.uid,
    text: messageText,
    sent: firebase.firestore.FieldValue.serverTimestamp(),
  });
};

答案1

得分: 2

如果我正确理解您的问题("看起来函数没有等待firebase.auth初始化"),您有两种可能的解决方案:

解决方案1:在Auth对象上设置观察者

文档中所解释,您可以使用onAuthStateChanged()方法在Auth对象上设置观察者:

通过使用观察者,您可以确保在获取当前用户时,Auth对象不处于中间状态,例如初始化状态。

因此,您可以将您的代码修改如下:

// 检索DMs
function messagesWith(uid) {
  return dmCollection(uid).orderBy('sent', 'desc').get();
};

// 发送DM
function sendDM(toUid, messageText) {
  return dmCollection(toUid).add({
    from: firebase.auth().currentUser.uid,
    text: messageText,
    sent: firebase.firestore.FieldValue.serverTimestamp(),
  });
};

// 根据当前用户和他尝试联系的用户生成正确的子集合
function dmCollection(toUid) {

  if (toUid === null) {
    // 如果未定义目标用户,我们将其设置为下面的值
    toUid = 'fixed_value';
  };
  const idPair = [firebase.auth().currentUser.uid, toUid].join('_').sort();
  return firebase.firestore().collection('dms').doc(idPair).collection('messages');
};

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    var messageText = '....';
    sendDM(user.uid, messageText)
  } else {
    // 没有用户登录。
  }
});

解决方案2:使用currentUser属性

您还可以"使用相同文档中解释的currentUser属性获取当前登录用户"。 "如果用户未登录,currentUser为null"。

在这种情况下,您可以执行以下操作:

var user = firebase.auth().currentUser;

if (user) {
  var messageText = '....';
  sendDM(user.uid, messageText);
} else {
  // 没有用户登录。
  // 提示用户登录,例如重定向到登录页面
}

选择哪种解决方案?

这取决于您希望基于用户的uid何时调用函数:

  • 如果您希望在用户登录后立即调用函数,使用解决方案1。
  • 如果您希望在另一个特定时刻调用函数(例如,按照用户操作),请使用解决方案2。
英文:

If I correctly understand your problem ("it looks like the function is not waiting for firebase.auth initialization"), you have two possible solutions:

###Solution 1: Set an observer on the Auth object###

As explained in the documentation, you can set an observer on the Auth object with the onAuthStateChanged() method:

> By using an observer, you ensure that the Auth object isn't in an
> intermediate state—such as initialization—when you get the current
> user.

So you would modify your code as follows:

// retrieve DMs
function messagesWith(uid) {
  return dmCollection(uid).orderBy('sent', 'desc').get();
};


// send a DM
function sendDM(toUid, messageText) {
  return dmCollection(toUid).add({
	from: firebase.auth().currentUser.uid,
	text: messageText,
	sent: firebase.firestore.FieldValue.serverTimestamp(),
  });
};

// generate the right SubCollection depending on current User and the User he tries to reach
function dmCollection(toUid) {

  if (toUid === null) {
	// If no destination user is definer, we set it to the below value
	toUid = 'fixed_value';
  };
  const idPair = [firebase.auth().currentUser.uid, toUid].join('_').sort();
  return firebase.firestore().collection('dms').doc(idPair).collection('messages');
};


firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
	var messageText = '....';
	sendDM(user.uid, messageText)
  } else {
	// No user is signed in.
  }
});

###Solution 2: Use the currentUser property###

You could also "get the currently signed-in user by using the currentUser property" as explained in the same doc. "If a user isn't signed in, currentUser is null".

In this case you would do:

var user = firebase.auth().currentUser;

if (user) {
  var messageText = '....';
  sendDM(user.uid, messageText);
} else {
  // No user is signed in.
  // Ask the user to sign in, e.g. redirect to a sign in page
}

###Which solution to choose?###

It depends how you want to call the function(s) based on the user uid.

  • If you want to call the function(s) immediately after the user is signed in, use Solution 1.
  • If you want to call the function(s) at another specific moment (e.g. following a user action), use Solution 2.

huangapple
  • 本文由 发表于 2020年1月6日 20:23:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/59612070.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定