Guardar la base de datos de Cordova en Dropbox

Cómo guardar su base de datos para Dropbox (y cómo restaurarla) desde una aplicación de Cordova – Sólo Android (parte 3)

En esta tercera parte de nuestro artículo tutorial sobre cómo guardar su base de datos a Dropbox (aquí abreviado como DBX, en mayúsculas) desde una aplicación móvil de Cordova para dispositivos Android, Nos concentraremos en los pasos específicos necesarios para

  • conectarse a DBX y guardar en Dropbox nuestro archivo de volcado de mysql
  • recuperarlo de DBX y usarlo para completar nuestra base de datos

esto puede ser útil si nuestro usuario ha desinstalado nuestra aplicación o si por alguna razón el archivo de respaldo local se ha perdido o dañado.

Crear una aplicación de Dropbox

Lo primero que tenemos que hacer es crear una aplicación en el panel de Dropbox para iniciar sesión con éxito usando Oauth2.. Se puede encontrar un muy buen tutorial. aquí y te animo a que lo leas atentamente si tienes alguna duda. Aquí resumo rápidamente los pasos necesarios:

  1. navegar a https://www.dropbox.com/developers
  2. Inicie sesión en su cuenta 😉
  3. cree una nueva aplicación haciendo clic en el «Crea tu aplicación» enlace en el centro de la página
  4. elige la API de Dropbox
  5. decida si desea / necesita acceso completo a DBX o si solo necesita acceder a una sola carpeta creada específicamente para su aplicación
  6. establezca un nombre para su aplicación y haga clic en el azul «Crear aplicación» botón
  7. toma nota de tu clave de la aplicación y tu App secreta; también observe y recuerde el URI de redireccionamiento, que para Oauth2 debe ser https://www.dropbox.com/1/oauth2/redirect_receiver

Ahora se crea su aplicación DBX y le permitirá iniciar sesión en DBX desde su aplicación móvil híbrida.

Obtener el SDK de Dropbox Javascript

Para utilizar la API, debe instalar el SDK de Dropbox JavaScript, una interfaz javascript para la API de Dropbox v2. Para instalarlo, abra un símbolo del sistema o una ventana de terminal y escriba el siguiente comando:

npm install --save dropbox

Ahora, si estas familiarizado con paquete web o navegador, puede usar el SDK como se explica en el repositorio oficial de Github. Pero si no quieres o simplemente no sabes cómo usar esas herramientas, vaya al directorio donde se ha instalado el SDK, copia el archivo Dropbox-sdk.min.js desde el directorio dist del paquete a www / js carpeta de su aplicación y luego vincularla en su índice.html:

<de script type ="text / javascript" src ="js / Dropbox-sdk.min.js"></guión>

Ahora finalmente estamos listos para rockear!

Volver a la aplicación

Ahora es el momento de instalar el último plugin que necesitamos para seguir adelante, cordova-plugin-inappbrowser. Simplemente navegue al directorio raíz de su proyecto con su CLI y escriba:

Los complementos de cordova agregan cordova-plugin-inappbrowser

Una vez instalada, tenemos que modificarlo un poco. De hecho, si no aplicáramos esta pequeña solución, después de haber iniciado sesión en la cuenta DBX int, Permaneceríamos bloqueados en una página en blanco y nunca seríamos redirigidos a nuestra aplicación. Así que abre en tu editor de código el archivo plataformas / android / platform_www / plugins / cordova-plugin-inappbrowser / www / inappbrowser.js. Cerca del final del guión, alrededor de la línea 110 más o menos, inmediatamente después de esta línea:

strWindowFeatures = strWindowFeatures || "";

Pon lo siguiente 3 líneas:

Si (strUrl == 'https://www.dropbox.com/1/oauth2/redirect_receiver ') {
	strWindowFeatures + = "ubicación = no,oculto = si";
}

De esta manera, le estamos diciendo a inappbrowser que se oculte si la URL es la URL de redireccionamiento establecida en nuestra aplicación DBX.

Permitir origen?

Otro problema con el que me encuentro es el mensaje de error devuelto por Dropbox cuando intenté guardar un archivo la primera vez. Este fue el mensaje:

Error: La solicitud ha sido cancelada Posibles causas: la red está desconectada, El origen no está permitido por Access-Control-Allow-Origin, la página se está descargando, etc..

Para acortar una historia larga, simplemente reemplace su meta de Política de seguridad de contenido en su índice.html Con este (o agregarlo, si falta):

<meta http-equiv ="Contenido-Seguridad-Política" = contenido"default-src *; estilo-src 'auto' http://* 'Inseguro-inline'; script src 'auto' http://* 'Inseguro-inline' 'insegura-eval'; medios de comunicación-src *" />

El error se fue,y la aplicación se ejecuta. Excelente!

Configurar la conexión de Dropbox

Como se dijo arriba, DBX API usa OAuth2 para administrar la autenticación. Entonces, lo primero que tenemos que hacer es preparar algunas cosas para permitir que nuestra aplicación inicie sesión en DBX:

var CLIENT_ID = 'xxxxxxxxxxxxxxx';//we use App key as our client id 
var dbxt; //an object to store our Dropbox connection and its access token 
var dbx = new Dropbox({Identificación del cliente: IDENTIFICACIÓN DEL CLIENTE}); //el objeto inicial de Dropbox

Coloque las líneas de arriba inmediatamente después del app.initialize llama, antes que las otras funciones que ya hemos escrito para operar en nuestra base de datos. Esto no es obligatorio, por supuesto: Puedes ponerlo en cualquier lugar con 🙂 el que te sientas más cómodo

Cambios en la interfaz de usuario

Para seguir adelante con nuestro pequeño proyecto, ahora tenemos que cambiar ligeramente nuestra interfaz de usuario. Es decir, Modificaremos el comportamiento de los botones que exportan e importan respectivamente la base de datos: en lugar de realizar estas acciones, solo harán visible otro div con 2 botones para permitir al usuario elegir

  • si exporta la base de datos solo localmente o incluso a DBX
  • si importa la base de datos desde un archivo local o desde DBX

Cambios en el marcado

Vamos a cambiar nuestro índice.html primero: simplemente reemplace la sección de botones con el siguiente marcado:

		<div class ="centrado">
			<h3>Seleccione un país:</h3>
			<seleccionar id ="países">
			</Seleccione>
			<a href ="#" id ="createDB" class ="btn btn-primario">Crea tablas</un>
			<a href ="#" id ="emptyDB" class ="btn btn-primario">Base de datos vacía</un>
			<a href ="#" id ="setExportOptions" class ="btn btn-primario">Exportar base de datos</un>
			<div id ="exportOptions" class ="impexpOptions">
				<la>
					<en>
						<a href ="#" id ="exportDB" class ="btn btn-inline btn-primario">Guardar localmente</un>
					</en>
					<en>
						<a href ="#" id ="exportDbToDropbox" class ="btn btn-inline btn-primario">Guardar en dropbox</un>
					</en>
				</la>
			</Div>
			<a href ="#" id ="setImportOptions" class ="btn btn-primario">Importar base de datos</un>
			<div id ="importOptions" class ="impexpOptions">
				<la>
					<en>
						<a href ="#" id ="importDB" class ="btn btn-inline btn-primario">Restaurar desde dispositivo</un>
					</en>
					<en>
						<a href ="#" id ="importDbFromDropbox" class ="btn btn-inline btn-primario">Restaurar desde Dropbox</un>
					</en>
				</la>
			</Div>
		</Div>

En tus índice.css archivo agregamos algunas reglas:

.BTN-en línea{
    margen: 10Px 0 !importante;
    relleno: 5px 10px !importante;
}
.impexpOptions{
	monitor: ninguna;
}
.impexpOptions ul{
	relleno: 0;
}
.impexpOptions ul li{
	monitor: bloque-en línea;
}

Cambios en la lógica

En tus índice.js Buscar los manejadores de eventos de nuestro botón y reemplazarlos por los siguientes:

	$('#createDB').hacer clic(función (mi) {
		e.preventDefault();
		createTables();
	});

	$('#emptyDB').hacer clic(función (mi) {
		e.preventDefault();
		dropTables();
	});

	$('#setExportOptions').hacer clic(función (mi) {
		e.preventDefault();
		$('#exportOptions').slideToggle(400, función(){
			$('html, cuerpo').animar({
				scrollTop: $('#exportOptions').compensar().parte superior
			}, 600);
		});
	});

	$('#exportDB').hacer clic(función (mi) {
		e.preventDefault();
		exportCopia de seguridad(falso);
	});

	$('#exportDbToDropbox').hacer clic(función (mi) {
		e.preventDefault();
		exportCopia de seguridad(cierto);
	});

	$('#setImportOptions').hacer clic(función (mi) {
		e.preventDefault();
		$('#importOptions').slideToggle(400, función () {
			$('html, cuerpo').animar({
				scrollTop: $('#importOptions').compensar().parte superior
			}, 600);
		});
	});

	$(«#importDB»).hacer clic(función (mi) {
		e.preventDefault();
		importCopia de seguridad(falso);
	});

	$('#importDbFromDropbox').hacer clic(función (mi) {
		e.preventDefault();
		importCopia de seguridad(cierto);
	});

Guau, Aquí se cambian varias cosas! Entonces, Resumamos los cambios:

  • hemos añadido 2 Controladores de eventos para botones con ID setExportOptions y setImportOptions: Aquí solo mostramos divs ocultos con botones para realizar acciones reales (Tenga en cuenta que hemos agregado una devolución de llamada para desplazarse por la página y obtener siempre el 2 Nuevos botones visibles)
  • Además de los botones con identificadores exportDB y importDB hemos añadido 2 Nuevos botones con identificadores exportDbToDropbox y importDbFromDropbox
  • profesión exportCopia de seguridad() y importCopia de seguridad() funciones, Hemos usado un parámetro booleano que no usábamos antes: Este parámetro se establece en false para exportar la base de datos solo localmente y para importar la base de datos desde un archivo de copia de seguridad local; se establece en true, en lugar, si queremos guardar nuestra copia de seguridad en nuestra cuenta DBX o si queremos restaurar nuestra base de datos desde un archivo de copia de seguridad remota guardado en nuestra cuenta DBX

De hecho, Vamos a modificar nuestro exportCopia de seguridad() y importCopia de seguridad() funciones para aceptar tal como parámetro y actuar de acuerdo con su valor.

Conectando a Dropbox

Antes de reescribir nuestras funciones para integrar código DBX, veamos cómo gestionamos la conexión a través de Oauth2. Primero el código (extracto de exportCopia de seguridad() función):

Si (dbxt == nulo) {
	dbx.authenticateWithCordova(función (accessToken) {
		dbxt = nuevo Dropbox({accessToken: accessToken});
                //tus cosas aquí
} más {
        //tus cosas aquí
}

Analicemos este código. primero, comprobamos si dbxt es nulo. Que es dbxt? Es una conexión DBX tokenizada, ese es el objeto que usamos una vez autenticado en DBX. Como recuerdas, hemos declarado este objeto inmediatamente después de la llamada a aplicación .. inicializada método. E inmediatamente después de haber declarado este objeto, habíamos configurado otro objeto que usamos para realizar el inicio de sesión en DBX, el dbx objeto:

var dbxt;
var dbx = nuevo Dropbox({Identificación del cliente: IDENTIFICACIÓN DEL CLIENTE})

Entonces, si aún no hemos establecido una conexión válida a DBX (dbxt es nulo), A continuación, usamos el método authenticateWithCordova() Método del objeto dbx para realizar el inicio de sesión y obtener un accessToken que identificará nuestra conexión como una conexión autorizada. Este token de acceso será una propiedad de la propiedad dbxt objeto que nos permitirá realizar las acciones que necesitamos hacer. Si ya hemos establecido una conexión con DBX, simplemente seguimos adelante con nuestras cosas 🙂

Carga de archivos

Para exportar nuestra base de datos a DBX tenemos que usar el comando filesUpload() y archivosDescargar() Métodos de nuestro dbxt objeto. Veamos nuestro nuevo exportCopia de seguridad() función:

función exportBackup(toDropbox) {
	var successFn = función (.sql) {
		window.resolveLocalFileSystemURL(cordova.file.dataDirectory, función (dirEntry) {
			dirEntry.getDirectory('/ dropboxTestBackup', {crear: cierto}, función (dirEntry) {
				dirEntry.getFile('dropboxTestBackup.sql', {crear: cierto}, función (fileEntry) {
					alerta("Crear el archivo: " + fileEntry.name + '. Puede encontrarlo en su almacenamiento interno en la siguiente ruta: Android / data / com.example.dropboxTest / files / dropboxTestBackup / ');
					writeFile(fileEntry, .sql);
					Si (toDropbox) {
						Si (dbxt == nulo) {
							dbx.authenticateWithCordova(función (accessToken) {
								dbxt = nuevo Dropbox({accessToken: accessToken});
								dbxt.filesUpload({
									sendero: '/' + fileEntry.name,
									contenido: .sql,
									modo: 'Sobrescribir',
									silencio: cierto
								}).luego(función (respuesta) {
									alerta('Su copia de seguridad se ha subido correctamente a su Dropbox!')
									consola.log(respuesta);
								}).captura(función (error) {
									alerta('Error al guardar el archivo en tu Dropbox! Puede volver a intentarlo o copiar manualmente el archivo Android / data / com.webintenerife.qbook / files / qbookBackup / qbook.sql en su carpeta de Dropbox o en otro lugar seguro '.)
									console.error(mensaje de error);
								});
							}, función (mi) {
								consola.log("autenticación fallida de Dropbox");
								consola.log(e.mensaje);
							});
						} más {
							consola.log('exportar: usuario ya autenticado ');
							dbxt.filesUpload({
								sendero: '/' + fileEntry.name,
								contenido: .sql,
								modo: 'Sobrescribir',
								silencio: cierto
							}).luego(función (respuesta) {
								alerta('Su copia de seguridad se ha subido correctamente a su Dropbox!')
								consola.log(respuesta);
							}).captura(función (error) {
								alerta('Error al guardar el archivo en tu Dropbox! Puede volver a intentarlo o copiar manualmente el archivo Android / data / com.webintenerife.qbook / files / qbookBackup / qbook.sql en su carpeta de Dropbox o en otro lugar seguro '.)
								consola.log(mensaje de error);
							});
						}
					}
				});
			}, onErrorCreateFile);
		}, onErrorCreateDir);
	};
	cordova.plugins.sqlitePorter.exportDbToSql(.db, {
		successFn: successFn
	});
}

filesUpload() la función es bastante simple. Lo pasamos siguiendo parámetros:

  • sendero: la ruta del archivo que queremos
  • contenido: los datos para escribir en el archivo (esto se pasa a la función de devolución de llamada successFn() por cordova.plugins.sqlitePorter.exportDbToSql() función)
  • modo: selecciona qué hacer si el archivo ya existe (los valores posibles se suman, sobrescribir y actualizar: http://dropbox.github.io/dropbox-sdk-js/global.html#FilesWriteMode).
  • silencio: un valor booleano para establecer si queremos recibir una notificación de DBX cuando el archivo ha sido cambiado (hasta donde se, en julio 21, 2017 Esto no funciona)

Una vez que se completa la carga, avisamos al usuario que el trabajo está hecho.

Descarga de archivos

Y ahora ve a ver el importCopia de seguridad() función:

función importBackup(desdeDropbox) {
	Si (!desdeDropbox) {
		var rutaToArchivo = cordova.archivo.datosDirectorio + '/dropboxTestBackup/dropboxTestBackup.sql';
		window.resolveLocalFileSystemURL(pathToFile, función (fileEntry) {
			fileEntry.file(función (archivo) {
				var reader = nuevo FileReader();
				reader.onloadend = función (mi) {
					var successFn = función () {
						alerta('Base de datos restaurada con éxito!');
						loadPaíses();
						loadUsers();
					};
					cordova.plugins.sqlitePorter.importSqlToDb(.db, this.result, {
						successFn: successFn
					});
				};
				reader.readAsText(archivo);
			}, onErrorLoadFile);
		}, onErrorLoadFs);
	} más {
		Si (dbxt == nulo) {
			dbx.authenticateWithCordova(función (accessToken) {
				dbxt = nuevo Dropbox({accessToken: accessToken});
				dbxt.filesDescargar({
					sendero: "/dropboxTestBackup.sql"
				}).luego(función (respuesta) {
					var reader = nuevo FileReader();
					reader.readAsText(response.fileBlob);
					reader.onloadend = función () {
						var successFn = función () {
							alerta('Base de datos restaurada con éxito!');
							loadPaíses();
							loadUsers();
						};
						var errorFn = función (mi) {
							consola.log('Error al importar la base de datos');
							consola.log(e.mensaje);
						};
						cordova.plugins.sqlitePorter.importSqlToDb(.db, this.result, {
							successFn: successFn,
							errorFn: errorFn
						});
					};
				}).captura(función (error) {
					alerta("Error al leer el archivo de tu Dropbox!');
					console.error(mensaje de error);
				});
			}, función () {
				consola.log("No pudiste iniciar sesión en tu Dropbox.");
			});
		} más {
			dbxt.filesDescargar({
				sendero: "/dropboxTestBackup.sql"
			}).luego(función (respuesta) {
				var reader = nuevo FileReader();
				reader.readAsText(response.fileBlob);
				reader.onloadend = función () {
					var successFn = función () {
						alerta('Base de datos restaurada con éxito!');
						loadPaíses();
						loadUsers();
					};
					var errorFn = función (mi) {
						consola.log('Error al importar la base de datos');
						consola.log(e.mensaje);
					};
					cordova.plugins.sqlitePorter.importSqlToDb(.db, this.result, {
						successFn: successFn,
						errorFn: errorFn
					});
				};
			}).captura(función (error) {
				alerta("Error al leer el archivo de tu Dropbox!');
				console.error(mensaje de error);
			});
		}
	}
}

Es un poco más largo pero es tan simple como el anterior. Una vez que hemos establecido una conexión válida a DBX, podemos descargar el archivo que queramos y pasárselo a nuestro lector para que lo lea y, si todo esta bien, para pasarlo al plugin SQLite Porter para importar el contenido del archivo en nuestra base de datos. Todo listo!

Te sugiero que sigas el tutorial paso a paso para comprender mejor su lógica. Pero para los muy perezosos he preparado un pequeño archivo que pueden descargar haciendo clic en el botón de abajo. El archivo contiene solo los tres archivos principales índice.html, índice.css, y índice.js: solo extráelo en tu www/ directorio y responda sí para sobrescribir los archivos existentes.

Archivos principales de la aplicación

Solo recuerde reemplazar la clave de la aplicación falsa en la línea index.js 21 con su app_key de DBX!

Conclusiones

La aplicación es cruda, Lo sé, pero espero que pueda ilustrar con suficiente claridad cómo puede conectarse a DBX desde su aplicación Android Cordova y cómo guardar / restaurar una base de datos. Probablemente desee agregar una ruleta o algo más para notificar al usuario que la aplicación se está ejecutando mientras se exporta o importa la base de datos., pero esto no era crucial para nuestro objetivo aquí, así que no lo cubrí.

Lo que realmente no me gusta es la forma en que inappbrowser el complemento permanece atascado en una página en blanco mientras se conecta a DBX, pero todavía no he encontrado una solución válida. Pensé que podría ser posible abrir una página remota personalizada en un servidor y usar Php o ASP para hacer el trabajo sucio antes de volver a la aplicación, pero esto insertaría un tercer elemento (un servidor externo) Me gustaria evitar. Tienes alguna idea? Hágamelo saber!

 


 

2 comentarios en “Cómo guardar su base de datos para Dropbox (y cómo restaurarla) desde una aplicación de Cordova – Sólo Android (parte 3)”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *