Localhost backend debugging from android device in visual studio, a beginners mistake

cordova azure api debugging on localhost throws error “Failed to load resource: net::ERR_CONNECTION_REFUSED”

Summary:
No! your phone will not connect to your computer through the usb when debugging from Visual Studio using the “device” option.

Scenario: A simple getting started Cordova app with azure backend. Using Visual Studio 2015 and Visual Studio Tools for Apache Cordova. https://azure.microsoft.com/sv-se/documentation/articles/app-service-mobile-cordova-get-started/

Adding push notifications. https://azure.microsoft.com/sv-se/documentation/articles/app-service-mobile-cordova-get-started-push/

Story:

I have been banging my head for a couple of days and cold not figure out what was wrong. When connecting to my backend in Azure the app was working correct, but not when running locally for debugging.

When searching www.stackoverflow.com and googling for the error I got “Failed to load resource: net::ERR_CONNECTION_REFUSED” I got lured away into believing this was related to Cross-origin resource sharing (CORS).

I have tried all variants of CORS settings I could imagine but nothing worked, I would still get the same error “Failed to load resource: net::ERR_CONNECTION_REFUSED

ERR_CONNECTION_REFUSED

The big mistake?
Well.. I assumed the “device” debugging feature in Visual Studio was using my computers infrastructure, as in network connection, and it was first when I switched to another phone that was not connected to Internet I found that it could not login to my active directory in Azure (used by the app), hence I understood that it must be the same problem when trying to reach my developer machine.

The solution

  1. Make sure the phone is connected to the same network as your developer machine and no firewall rules are blocking access to the local IIS (the phone must be able to open the machines web server)
  2. Use the real (local) IP address in the app settings, do not use “http://localhost“.
  3. (if you are using Azure Mobile Apps) When calling the API you need to add the header “ZUMO-API-VERSION: 2.0.0” to your POST command. https://azure.microsoft.com/sv-se/documentation/articles/app-service-mobile-client-and-server-versioning/

 

My setup
Windows 10, Visual Studio 2015, Visual Studio Tools for Apache Cordova,
Microsoft Azure, Google Cloud, Sony Xperia Z5 compact (android 6.0 marshmallow),
Cordova CLI 6.0, cordova-plugin-ms-azure-mobile-apps, phonegap-plugin-push

A code sample
(the backend implementation is found in  https://azure.microsoft.com/sv-se/documentation/articles/app-service-mobile-cordova-get-started-push/)

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
 
 // code is from https://azure.microsoft.com/sv-se/documentation/articles/app-service-mobile-cordova-get-started/ with some modifications

 
(function () {
    "use strict";

    var client             // Connection to the Azure Mobile App backend
    var usingLocalBackendServer = true;
    var runningHost; //server address set depending on if you want to run in your local IIS or Azure

    // Add an event listener to call our initialization routine when the host is ready
    document.addEventListener('deviceready', onDeviceReady, false);

    /**
     * Event Handler, called when the host is ready
     *
     * @event
     */
    function onDeviceReady() {
        if (usingLocalBackendServer) {
            //use your real ip address here if you want to be able to debug using "device" in visual studio
            // http://localhost will only work when emulating android on the same machine.
            runningHost = 'http://10.1.1.6/backendService/';
            
            // Create a connection reference to our Azure Mobile Apps backend 
            client = new WindowsAzure.MobileServiceClient(runningHost);
            
            //alternateLoginHost is needed if you want to login through your Azure AD
            client.alternateLoginHost = "https://yourBackend.azurewebsites.net/";
            
        } else {
            runningHost = 'https://yourBackend.azurewebsites.net/';
            // Create a connection reference to our Azure Mobile Apps backend
            client = new WindowsAzure.MobileServiceClient(runningHost);
        }
        
        initialize();
    }
    
    function initialize (){
        // register for push notifications.
        registerForPushNotifications();

        //// Wire up the UI Event Handler for sending message
        //$('#send-notification').submit(sendNotificationHandler);
    };
    
    // Register for Push Notifications (at Google Cloud Platform using Google Cloud Messaging API).
    // - Requires that phonegap-plugin-push is installed.
    var pushRegistration = null;
    function registerForPushNotifications() {
        pushRegistration = PushNotification.init({
            android: {
                senderID: '1234567890', //use your google cloud messaging "Project number"
                icon: 'phonegap',
                iconColor: 'blue'
            },
            // ios: {
                // alert: 'true',
                // badge: 'true',
                // sound: 'true'
            // },
            // wns: {

            // }
        });

        pushRegistration.on('registration', function (data) {
            client.push.register('gcm', data.registrationId); //register client in azure notification hub
            
            registerInBackend(data.registrationId); 
            
            //Here is a good place to test sending a notification back to the registred device
            //sendNotification(); 
        });

        pushRegistration.on('notification', function (data, d2) {

            //Do something when a messsage is recieved, such as adding it to a list of notifications and updating the interface to display unread messages
            alert(data.title, data.message); //test            
        });

        //handle errors
        pushRegistration.on('error', handleError);
    }

    
    /*
        $.ajax Code in registerInBackend is from         http://www.html5rocks.com/en/tutorials/cors/#toc-cors-from-jquery
        with some modifications
    */
    function registerInBackend(registrationId) {
        $.ajax({
            // The 'type' property sets the HTTP method.
            // A value of 'PUT' or 'DELETE' will trigger a preflight request.
            type: 'POST',

            // The URL to make the request to.
            url: runningHost + 'api/register/',

            // The 'contentType' property sets the 'Content-Type' header.
            // The JQuery default for this property is
            // 'application/x-www-form-urlencoded; charset=UTF-8', which does not trigger
            // a preflight. If you set this value to anything other than
            // application/x-www-form-urlencoded, multipart/form-data, or text/plain,
            // you will trigger a preflight request.
            contentType: 'text/plain',

            xhrFields: {
                // The 'xhrFields' property sets additional fields on the XMLHttpRequest.
                // This can be used to set the 'withCredentials' property.
                // Set the value to 'true' if you'd like to pass cookies to the server.
                // If this is enabled, your server must respond with the header
                // 'Access-Control-Allow-Credentials: true'.
                withCredentials: false
            },

            headers: {
                // Set any custom headers here.
                // If you set any non-simple headers, your server must include these
                // headers in the 'Access-Control-Allow-Headers' response header.
                // ZUMO-API-VERSION needed for the Azure Mobile Apps backend to allow the request
                // - https://azure.microsoft.com/sv-se/documentation/articles/app-service-mobile-client-and-server-versioning/
                'ZUMO-API-VERSION' : '2.0.0' 
            },

            //String or json data to send to the API
            data: registrationId,

            //Return json
            dataType: 'json',

            success: function (data) {
                // Here's where you handle a successful response.
                alert('success register: ' + data);
            },

            error: function (e) {
                // Here's where you handle an error response.
                // Note that if the error was due to a CORS issue,
                // this function will still fire, but there won't be any additional
                // information about the error.
                alert('error registerInBackend: ' + e);
            }
        });
    }

Leave a Reply

Your email address will not be published. Required fields are marked *


*