3

I am using the ConnectyCube React Native SDK and have obtained an app auth token using their API. This token is required when making further requests - for example when logging in as a user. Their documentation says:

Upgrade session token (user login)

If you have an application session token, you can upgrade it to a user session by calling login method:

var userCredentials = {login: 'cubeuser', password: 'awesomepwd'};

ConnectyCube.login(userCredentials, function(error, user) {

});

The problem is it that when I use this method, I get an error in response saying 'Token is required'.

If I were interfacing with a REST API, I would put the token in the header of the request, but obviously in this instance I can't. So the question is, where do I put the token? I have it, the documentation just doesn't tell you how to use it! Any help appreciated.

Mr. Robot
  • 1,334
  • 6
  • 27
  • 79

3 Answers3

0

Ok I came up with a fix. First of all I just tried passing the auth token in to the userCredntials object in the same way as in the documentation for social auth, that is absent from the description in my above code snippet taken from their docs.

Then I Promisified the API calls from within useEffect inside an async function to make sure everything was happening in the right order, and it works:

export default function App() {

  const createAppSession = () => {
    return new Promise((resolve, reject) => {
      ConnectyCube.createSession((error, session) => {
        !error
          ? resolve(session.token)
          : reject(error, '=====1=====');
      });
    })
  }

  const loginUser = (credentials) => {
    return new Promise((resolve, reject) => {
      ConnectyCube.login(credentials, ((error, user) => {
        !error
          ? resolve(user)
          : reject(error, '=====2=====');
      }));
    })
  }

  useEffect(() => {
    const ccFunc = async () => {
      ConnectyCube.init(...config)
      const appSessionToken = await createAppSession();
      const userCredentials = { login: 'xxxxx', password: 'xxxxxxx', keys: { token: appSessionToken } };
      const user = await loginUser(userCredentials);
      console.log(user);

    }
    ccFunc()
  }, []);
Mr. Robot
  • 1,334
  • 6
  • 27
  • 79
  • Update: this seems to be working but not for the reasons I though. It works without passing the token into the `userCredentials` object and I don't know why. It doesn't work if get rid of the line `const appSessionToken = await createAppSession();` which does't make sense because I'm not doing anything with what the function returns. Anyone from ConnectyCude like to comment?? – Mr. Robot Aug 07 '19 at 10:25
0

Hope it works.... please implement it by yourself...just take an understanding from code below. code says: send the username and password to api...if all ok then authenticate else throw error ...if all ok..then store the returned token is asyncStorage...you can create the storage by any name you like...and use the token eveywhere in your app.

SignInUser = async () => {
    
    this.setState({
     username: this.state.username,
     password:this.state.password,
   })

   if(this.state.username && this.state.password !== null){
    try{
      this.setState({
        loading:true
      })
      const response = await fetch('YOUR API', {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          username: this.state.username,
          password: this.state.password
        })
      });
      var promiseResponse = await response.json()
      console.log(promiseResponse.token);
      try {
        await AsyncStorage.setItem('STORE_YOUR_LOGIN_TOKEN_HERE', JSON.stringify(promiseResponse.token));
        console.log('Token Stored In Async Storage');
        let tokenFromAsync = await AsyncStorage.getItem('STORE_YOUR_LOGIN_TOKEN_HERE');
        console.log('Getting Token From Async...')
        tokenFromAsync = JSON.parse(tokenFromAsync)
        if(tokenFromAsync !== null){
          console.log(tokenFromAsync);
          this.setState({
            loading:false
          })
          this.props.navigation.navigate('Tabnav');
        }
        
      } catch (error) {
        // saving error
        console.log(`ERROR OCCURED ${error}`)
      }
      //this.props.navigation.navigate('Tabnav')
     } catch(error){
       console.log(`COULDN'T SIGN IN ${error}`)
     }
   } else {
     this.setState({
       msg:'Invalid Credentials',
       label:'red'
     });
   }
   
  
   
 } 
0

This is how i got the login to work in their sample react native app

1. i created a credentials object like this in my custom login function in src>components>AuthScreen>AuthForm.js

var credentials = {id:'',login: this.state.login,password: this.state.password}

2.I used their _signIn(credentials) function and set the 'id' attribute of my credentials object after their UserService.signin(credentials) resolved with a user object. (the resolved user object contained the logged-in user's id i.e user.id). Then it worked. This is how the code looked for the signin after the little tweak.

loginUser() { //my custom signin function

    var credentials = {id:'',login: this.state.login,password: this.state.password} //my credentials object
    this._signIn(credentials)

}

_signIn(userCredentials) { //their signin function
    this.props.userIsLogging(true);

    UserService.signin(userCredentials)
        .then((user) => {
            userCredentials.id =  user.id //setting id of my credentials object after promise resolved
            ChatService.connect(userCredentials) //using my credentials object with id value set
                .then((contacts) => {
                    console.warn(contacts)
                    this.props.userLogin(user);
                    this.props.userIsLogging(false);
                    Actions.videochat(); //login worked
                })
                .catch(e => {
                    this.props.userIsLogging(false);
                    alert(`Error.\n\n${JSON.stringify(e)}`);
                })
        })
        .catch(e => {
            this.props.userIsLogging(false);
            alert(`Error.\n\n${JSON.stringify(e)}`);
        })
}