Global variable with background process

Hello there,

I've got a DataField which need to 2 things in background:

The first time doing an OAuth

The second time download the json

I can't do this in one time because the background process is terminating before I log successfully

So how the 2 calls of onTemporalEvent can call a different function each time

I've tried:

 1.a property but it cannot be used in background

 2.a global variable but it seems not to be shared

The second call needs a token returned by the first call

    function onTemporalEvent() {
    	if(phase==1){
	        goOAuth();
	    }else{
	        goJson();
	    }
    }
    

  • My bad, I've solved with a Properties.setValue

  • If you're trying to do OAuth in the background (maybe from a watch face or a data field), things can get a bit complicated. Here is a quick rundown of what needs to happen.

    First, you want to register your app to be notified when an OAuth response arrives.

    // probably in App.onInstall
    Background.registerForOAuthResponseEvent();

    Then you want to issue the OAuth request:

    var params = {
        "scope" => Comm.encodeURL("https://www.serviceurl.com/"),
        "redirect_uri" => "http://localhost",
        "response_type" => "code",
        "client_id" => $.CLIENT_ID
    };
    
    // makeOAuthRequest triggers login prompt on mobile device
    Comm.makeOAuthRequest(
        "https://requesturl.com",
        params,
        "http://resulturl.com",
        Comm.OAUTH_RESULT_TYPE_URL,
        {"responseCode" => $.OAUTH_CODE, "responseError" => $.OAUTH_ERROR}
    );

    This will send the request and make a popup appear on the mobile phone. After the user completes the sign in, your app will be started in background mode and the ServiceDelegate will be notified that the response was received. At this time, you want to register a callback to receive the OAuth code.

    function onOAuthResponse() {
        Communications.registerForOAuthMessages(mOAuthProvider.method(:onOAuthCode));
    }

    If there is a pending OAuth message, it will invoke the given callback immediately. When the OAuth code callback is invoked, you will need to generate a web request to get the OAuth token and expiry information:

    function onOAuthCode(message) {
        if (message.data != null) {
    
            var params = {
                "grant_type" => "authorization_code",
                "code" => message.data[$.OAUTH_CODE]
            };
    
            var options = {
                :method => Comm.HTTP_REQUEST_METHOD_POST,
                :headers => {
                    "Content-Type" => Comm.REQUEST_CONTENT_TYPE_JSON,
                    "Authorization" => "Basic " + StringUtil.encodeBase64(CLIENT_ID + ":" + CLIENT_SECRET)
                }
            };
            
            Comm.makeWebRequest(url, params, options, self.method(:onAccessTokenResponse));
        } else {
            // return an error
        }
    }

    Finally, when the OAuth token exchange has completed and the token is returned, you can push that data to the foreground process to be saved.

    function onAccessToken(code, data) {
    
        var backgroundData = {};
        if(code == 200) {
            var accessToken = data["access_token"];
            var refreshToken = data["refresh_token"];
            var expiryInfo = Time.now().add(new Time.Duration(data["expires_in"]));
            
            backgroundData.put("type", "access_token");
            backgroundData.put("access_token", accessToken);
            backgroundData.put("refresh_token", refreshToken);
            backgroundData.put("expiration_time", expiryInfo);
        }
        else {
            // error getting token
        }
        
        Background.exit(backgroundData);
    }

    The foreground process just saves the data:

    function onBackgroundData(data) {
        Storage.setValue("backgroundData", data);
    }

    Now your background app can use the OAuth token. If the token has expired, you'll need to use the refresh token to get a new authorization token. You can make that request, get the new tokens, make the request you had wanted to make, and then when that response comes back you can push the tokens to the foreground process again.

  • Oh, so much thanks to you

    Thanks to you now I've found what missing in my code for OAuth, it is onOAuthResponse (the doc don't specify that I need to use it)

    And now my code works well

  • Hi I'm working on a new app that needs oauth, and learining while doing... I have a bit of a hard time to understand what to put as result_url in the makeOAuthRequest call. The oauth service I want to authorize to does not provide any information about any result_url, and the CIQ documentation does not document it so well. Appreciate your guidance here, thanks!!  

  • Never mind, I got it to work. i Just used the same as the Redirect_URI