Como usar o plug-in do Apache Cordova para os Aplicativos Móveis do Azure

Este guia ensina a executar cenários comuns usando o mais recente Plug-in do Apache Cordova para os Aplicativos Móveis do Azure. Se você for novo nos Aplicativos Móveis do Azure, primeiro conclua o Início Rápido dos Aplicativos Móveis do Azure para criar um back-end, criar uma tabela e baixar um projeto Apache Cordova pré-criado. Neste guia, abordaremos o Plug-in do Apache Cordova do lado do cliente.

Plataformas com Suporte

Esse SDK dá suporte à versão 6.0.0 do Apache Cordova e posterior nos dispositivos iOS, Android e Windows. O suporte de plataforma é o seguinte:

  • Android API 19 ou superior.
  • iOS versão 8.0 e posterior.

Aviso

Este artigo aborda informações para a versão da biblioteca v4.2.0, que foi desativada. Nenhuma outra atualização será feita nesta biblioteca, incluindo atualizações para problemas de segurança. Considere mudar para um cliente .NET, como o .NET MAUI , para obter suporte contínuo.

Configuração e pré-requisitos

Este guia pressupõe que você tenha criado um back-end com uma tabela. Os exemplos usam a tabela TodoItem dos guias de início rápido. Para adicionar o plug-in dos Aplicativos Móveis do Azure ao projeto, use o seguinte comando:

cordova plugin add cordova-plugin-ms-azure-mobile-apps

Para saber mais sobre como criar seu primeiro aplicativo do Apache Cordova, consulte a documentação.

Configurar um aplicativo Ionic v2

Para configurar corretamente um projeto Ionic v2, primeiro crie um aplicativo básico e adicione o plug-in Cordova:

ionic start projectName --v2
cd projectName
ionic plugin add cordova-plugin-ms-azure-mobile-apps

Adicione as seguintes linhas a app.component.ts para criar o objeto de cliente:

declare var WindowsAzure: any;
var client = new WindowsAzure.MobileServiceClient("https://yoursite.azurewebsites.net");

Agora, você pode criar e executar o projeto no navegador:

ionic platform add browser
ionic run browser

O plug-in Cordova para Aplicativos Móveis do Azure dá suporte a aplicativos Ionic v1 e v2. Somente os aplicativos Ionic v2 exigem a declaração adicional para o objeto WindowsAzure.

Criar uma conexão de cliente

Crie uma conexão de cliente por meio da criação de um objeto WindowsAzure.MobileServiceClient . Substitua appUrl pela URL de seu Aplicativo Móvel.

var client = WindowsAzure.MobileServiceClient(appUrl);

Trabalhar com tabelas

Para acessar ou atualizar dados, crie uma referência à tabela de back-end. Substitua tableName pelo nome da sua tabela

var table = client.getTable(tableName);

Depois que tiver uma referência de tabela, será possível trabalhar ainda mais com sua tabela:

Consultar uma referência de tabela

Depois que você tiver uma referência de tabela, será possível usá-la para consultar dados no servidor. As consultas são feitas em uma linguagem "parecida com LINQ". Para retornar todos os dados da tabela, use o seguinte código:

/**
 * Process the results that are received by a call to table.read()
 *
 * @param {Object} results the results as a pseudo-array
 * @param {int} results.length the length of the results array
 * @param {Object} results[] the individual results
 */
function success(results) {
   var numItemsRead = results.length;

   for (var i = 0 ; i < results.length ; i++) {
       var row = results[i];
       // Each row is an object - the properties are the columns
   }
}

function failure(error) {
    throw new Error('Error loading data: ', error);
}

table
    .read()
    .then(success, failure);

A função de sucesso é chamada com os resultados. Não use for (var i in results) na função de sucesso, pois isso causará a iteração de informações incluídas nos resultados quando outras funções de consulta (como .includeTotalCount()) forem usadas.

Para obter mais informações sobre a sintaxe de Query, confira a Documentação do objeto Query.

Filtragem de dados no servidor

É possível usar uma cláusula where na referência de tabela:

table
    .where({ userId: user.userId, complete: false })
    .read()
    .then(success, failure);

Você também pode usar uma função que filtra o objeto. Nesse caso, a variável this é atribuída ao objeto atual que está sendo filtrado. O código a seguir é uma funcionalidade equivalente ao exemplo anterior:

function filterByUserId(currentUserId) {
    return this.userId === currentUserId && this.complete === false;
}

table
    .where(filterByUserId, user.userId)
    .read()
    .then(success, failure);

Paginando pelos dados

Utilize os métodos take() e skip(). Por exemplo, se você quiser dividir a tabela em registros de 100 linhas:

var totalCount = 0, pages = 0;

// Step 1 - get the total number of records
table.includeTotalCount().take(0).read(function (results) {
    totalCount = results.totalCount;
    pages = Math.floor(totalCount/100) + 1;
    loadPage(0);
}, failure);

function loadPage(pageNum) {
    let skip = pageNum * 100;
    table.skip(skip).take(100).read(function (results) {
        for (var i = 0 ; i < results.length ; i++) {
            var row = results[i];
            // Process each row
        }
    }
}

O método .includeTotalCount() é usado para adicionar um campo totalCount ao objeto de resultados. O campo totalCount é preenchido com o número total de registros que retornariam se nenhuma paginação fosse usada.

Depois, você pode usar a variável de páginas e alguns botões da interface de usuário para fornecer uma lista de páginas; use loadPage() para carregar os novos registros de cada página. Implemente cache para agilizar o acesso a registros que já foram carregados.

Retornar dados classificados

Use os métodos de consulta .orderBy() ou .orderByDescending():

table
    .orderBy('name')
    .read()
    .then(success, failure);

Para obter mais informações sobre o objeto Query, confira a [documentação do objeto Query].

Inserir dados

Crie um objeto JavaScript com a data adequada e chame table.insert() de maneira assíncrona:

var newItem = {
    name: 'My Name',
    signupDate: new Date()
};

table
    .insert(newItem)
    .done(function (insertedItem) {
        var id = insertedItem.id;
    }, failure);

Após a inserção bem-sucedida, o item inserido retorna com os campos adicionais necessários para as operações de sincronização. Atualize seu próprio cache com essas informações para atualizações posteriores.

O SDK de Node.js Server dos Aplicativos Móveis do Azure dá suporte ao esquema dinâmico para fins de desenvolvimento. O esquema Dinâmico permite que você adicione colunas à tabela, especificando-as em uma operação de inserção ou atualização. Recomendamos que você desative o esquema antes de mover seu aplicativo para produção.

Modificar dados

Assim como o método .insert(), você deve criar um objeto de atualização e, em seguida, chamar .update(). O objeto de atualização deve conter a ID do registro a ser atualizada. Essa ID é obtida ao ler o registro ou ao chamar .insert().

var updateItem = {
    id: '7163bc7a-70b2-4dde-98e9-8818969611bd',
    name: 'My New Name'
};

table
    .update(updateItem)
    .done(function (updatedItem) {
        // You can now update your cached copy
    }, failure);

Excluir dados

Chame o método .del() para excluir um registro. Passe a ID em uma referência de objeto:

table
    .del({ id: '7163bc7a-70b2-4dde-98e9-8818969611bd' })
    .done(function () {
        // Record is now deleted - update your cache
    }, failure);

Autenticar usuários

O Serviço de Aplicativo do Azure oferece suporte à autenticação e autorização de usuários de aplicativos usando vários provedores de identidade externos: Facebook, Google, Conta da Microsoft e Twitter. Você pode definir permissões em tabelas para restringir o acesso a operações específicas apenas para usuários autenticados. Você também pode usar a identidade de usuários autenticados para implementar regras de autorização em scripts do servidor. Para obter mais informações, consulte o tutorial Introdução à autenticação .

Ao usar a autenticação em um aplicativo Apache Cordova, os seguintes plugins Cordova devem estar disponíveis:

Observação

Alterações de segurança recentes no iOS e no Android podem renderizar a autenticação de fluxo de servidor como não disponível. Nesses casos, você precisa usar um fluxo de cliente.

Dois fluxos de autenticação são suportados: um server flow e um client flow. O fluxo de servidor fornece a experiência de autenticação mais simples, pois depende da interface de autenticação da web do provedor. O fluxo de cliente permite uma integração mais profunda com recursos específicos do dispositivo, como logon único, uma vez que depende de provedores específicos e SDKs específicos do dispositivo.

Autenticar com um provedor (fluxo de servidor)

Para que os Aplicativos Móveis gerenciem o processo de autenticação em seu aplicativo, é necessário registrá-los no provedor de identidade. Em seguida, no Serviço de Aplicativo do Azure, você precisa configurar a ID e o segredo do aplicativo fornecidos por seu provedor. Para obter mais informações, consulte o tutorial Adicionar autenticação ao seu aplicativo.

Depois de registrar seu provedor de identidade, chame o método .login() com o nome do seu provedor. Por exemplo, para entrar com o Facebook, use o código a seguir:

client.login("facebook").done(function (results) {
     alert("You are now signed in as: " + results.userId);
}, function (err) {
     alert("Error: " + err);
});

Os valores válidos para o provedor são 'add', 'facebook', 'google', 'microsoftaccount' e 'twitter'.

Observação

Devido a questões de segurança, alguns provedores de autenticação podem não funcionar com um fluxo de servidor. Você precisa usar um método de fluxo de cliente nesses casos.

Nesse caso, o Serviço de Aplicativo do Azure gerencia o fluxo de autenticação OAuth 2.0. Ele exibe a página de logon do provedor selecionado e gera um token de autenticação do Serviço de Aplicativo após o logon bem-sucedido com o provedor de identidade. A função de logon, quando concluída, retorna um objeto JSON que expõe a ID do usuário e o token de autenticação do Serviço de Aplicativo nos campos userId e authenticationToken, respectivamente. Esse token pode ser armazenado em cache e reutilizado até que expire.

Autenticar com um provedor (fluxo de servidor)

Seu aplicativo também pode entrar em contato de forma independente com o provedor de identidade e fornecer o token retornado ao Serviço de Aplicativo para autenticação. Esse fluxo de cliente permite que você ofereça uma experiência de logon único aos usuários ou recupere dados do usuário adicionais do provedor de identidade.

Exemplo básico de autenticação social

Este exemplo usa o SDK de cliente do Facebook para a autenticação:

client.login("facebook", {"access_token": token})
.done(function (results) {
     alert("You are now signed in as: " + results.userId);
}, function (err) {
     alert("Error: " + err);
});

Esse exemplo pressupõe que o token fornecido pelo respectivo SDK do provedor é armazenado na variável 'token'. Os detalhes exigidos pelos provedores são um pouco diferentes. Confira a Documentação de autenticação e autorização do Serviço de Aplicativo do Azure para determinar a forma exata do conteúdo.

Obter informações sobre o usuário autenticado

As informações de autenticação podem ser recuperadas do ponto de extremidade /.auth/me usando uma chamada HTTP com qualquer biblioteca HTTP/REST. Certifique-se de definir o cabeçalho X-ZUMO-AUTH ao token de autenticação. O token de autenticação está armazenado em client.currentUser.mobileServiceAuthenticationToken. Por exemplo, para usar a API de busca:

var url = client.applicationUrl + '/.auth/me';
var headers = new Headers();
headers.append('X-ZUMO-AUTH', client.currentUser.mobileServiceAuthenticationToken);
fetch(url, { headers: headers })
    .then(function (data) {
        return data.json()
    }).then(function (user) {
        // The user object contains the claims for the authenticated user
    });

O Fetch está disponível como um pacote npm ou para download do navegador do CDNJS. Os dados são recebidos como um objeto JSON.

Configurar o Serviço de Aplicativo Móvel para URLs de redirecionamento externo.

Vários tipos de aplicativos do Apache Cordova usam uma funcionalidade de loopback para manipular fluxos de Interface do usuário do OAuth. Fluxos de interface do usuário OAuth causam problemas, pois o serviço de autenticação só sabe utilizar seu serviço por padrão. Exemplos de fluxos de interface do usuário OAuth problemáticos incluem:

  • O emulador Ripple.
  • Recarregamento dinâmico com Ionic.
  • Executando o back-end móvel localmente
  • A execução do back-end móvel em um Serviço de Aplicativo do Azure diferente que forneceu a autenticação.

Siga estas instruções para adicionar as definições locais à configuração:

  1. Faça logon no Portal do Azure

  2. Selecione Todos os recursos ou Serviços de Aplicativos e clique no nome do Aplicativo Móvel.

  3. Clique em Ferramentas

  4. Clique em Gerenciador de Recursos no menu OBSERVAR e clique em Ir. Uma nova janela ou guia é aberta.

  5. Expanda os nós config, authsettings do seu site no painel de navegação esquerdo.

  6. Clique em Editar

  7. Procure o elemento "allowedExternalRedirectUrls". Ele pode ser definido como nulo ou uma matriz de valores. Altere o valor para o seguinte:

    "allowedExternalRedirectUrls": [
        "http://localhost:3000",
        "https://localhost:3000"
    ],
    

    Substitua as URLs pelas URLs do seu serviço. Exemplos incluem http://localhost:3000 (para o serviço de exemplo Node.js) ou http://localhost:4400 (para o serviço Ripple). No entanto, essas URLs são exemplos – sua situação, incluindo para os serviços mencionados nos exemplos, pode ser diferente.

  8. Clique no botão Leitura/Gravação no canto superior direito da tela.

  9. Clique no botão verde PUT .

As configurações são salvas neste momento. Não feche a janela do navegador até que as configurações sejam salvas. Além disso, adicione essas URLs de loopback às configurações de CORS para o Serviço de Aplicativo:

  1. Faça logon no Portal do Azure
  2. Selecione Todos os recursos ou Serviços de Aplicativos e clique no nome do Aplicativo Móvel.
  3. A folha Configurações abre automaticamente. Se não for, clique em Todas as Configurações.
  4. Clique em CORS no menu de API.
  5. Digite a URL que você deseja adicionar na caixa fornecida e pressione Enter.
  6. Insira mais URLs, conforme o necessário.
  7. Clique em Salvar para salvar as configurações.

É necessário cerca de 10 a 15 segundos para que as novas configurações tenham efeito.