Open georgobermayr opened 7 years ago
This issue has been occurring for us as well.
Regardless of the form of authentication, it seems that in some instances Meteor.userId()
will return null
. It does not seem very predictable, and when I use Meteor.collection('users').find()
, the user exists in the collection with the correct _id
.
Edit:
I have actually been able to reproduce the error on my end. When you use Accounts.createUser
to create a new user, Meteor automatically logs in the new account. This works as intended, except that Meteor.userId()
will return as null
on the client even though the user is logged in. I fixed this by using a block similar to this:
Accounts.createUser({email, password}, (err) => {
if (Meteor.userId() === null) {
Meteor.loginWithPassword(email, password, (e) => {
if (e) {
console.log(e);
} else {
// do stuff here
}
});
} else {
if (err) {
console.log(err);
} else {
// do stuff here
}
}
});
I also have the issue with userId
when Meteor reconnects -- it is set back to null on reconnect.
I have found a way around the issue of reconnects where the userId
is set to null:
let wasDisconnected = false;
if (!Meteor.status().connected) {
wasDisconnected = true;
}
Meteor.waitDdpConnected(() => {
if (wasDisconnected) {
Meteor._loadInitialUser().then(() => {
// your code here which requires userId to be set correctly
});
} else {
// your code here which requires userId to be set correctly
}
});
_loadInitialUser()
comes from the Meteor.connect()
function.
If you omit this section:
Meteor._loadInitialUser().then(() => { ... });
Then Meteor.userId()
will be set correctly on the client, but any Meteor.call()
s will return null
for this.userId
on the server.
I was now able to circle back to the issue and do some more digging. I'm still not able to reproduce the issue so I implemented a fix based an my analysis of react-native-meteor. In my startup saga I do something like this:
const selectUser = (state) => {
return Selectors.getUser(state, state.auth.userId)
}
const selectUserToken = (state) => {
return Selectors.getUserToken(state)
}
const USER_TOKEN_KEY = 'reactnativemeteor_usertoken'
export function * startup (api, action) {
const user = yield select(selectUser)
if (user) {
const userToken = yield select(selectUserToken)
const storedToken = yield call(getStoredToken)
if (userToken !== storedToken) {
const setToken = yield call(setUserToken, userToken)
}
}
}
const getStoredToken = () => {
return new Promise(function (resolve, reject) {
AsyncStorage.getItem(USER_TOKEN_KEY, (error, result) => {
if (error) resolve(error)
else resolve(result)
})
})
}
const setUserToken = (token) => {
return new Promise(function (resolve, reject) {
AsyncStorage.setItem(USER_TOKEN_KEY, token, (error) => {
if (error) resolve(error)
})
})
}
So I store the Meteor userToken in my own Auth store too. On startup I check, if the reactnativemeteor_usertoken is still present. If not, I set it again from my copy.
I'm not 100% sure if this a reliable fix, but from my tests so far it looks fine.
Hi,
in our app, we have classic password accounts as well as Facebook and Twitter accounts. For that we implemented our own login handlers for the oAuth process. We discovered an issue with react-native-meteor, that with Facebook and Twitter login handlers the resume token is not written to the async store. This caused some issues with Meteor.userId() returning null after changes to the connection. So we added the key to the async store on our own. The code for this looks something like this:
This works fine and userId is set.
However we have some very rare cases now, in which the userId got lost later in the process. We don't know the exact circumstances when this happens, but after some time in the app (and probably some connection changes) the userId is null again. Is there any scenario where the the userId is cleared by react-native-meteor? Is there any way we could work around this? Is there a fix?
Thank you! Georg