user10800954
user10800954

Reputation:

Wait for firebase.auth initialization before reading another function

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

Upvotes: 0

Views: 2132

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83191

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.

Upvotes: 2

Related Questions