Docs Menu
Docs Home
/ /
Servicios de aplicaciones Atlas

Tutorial: Atlas Device Sync para React Native

Tiempo estimado para completar: 30 minutos, dependiendo de su experiencia con React Native

Puede utilizar el SDK de Realm React Native y @realm/reaccionar Para crear una aplicación móvil con React Native. Este tutorial te muestra cómo crear tu propia aplicación con Flexible Sync.

Para este tutorial, comenzaremos con una aplicación de plantilla TypeScript prediseñada para ver cómo encaja todo.

La aplicación es una plantilla prediseñada que incluye una aplicación React Native funcional (frontend) y sus archivos de configuración de aplicación de App Services correspondientes (backend).

La aplicación de plantilla es una aplicación básica de lista de tareas pendientes que permite a los usuarios hacer varias cosas para administrar sus tareas:

  • Cree cuentas de correo electrónico/contraseña e inicie y cierre sesión en la aplicación.

  • Crear, leer, actualizar y eliminar sus propias tareas.

  • Ver todas las tareas, incluso si el usuario no es el propietario.

Una vez que la aplicación de plantilla esté en funcionamiento, agregará una nueva priority campo al modelo Item existente y actualice la suscripción de Sincronización Flexible para que solo muestre elementos dentro de un rango de prioridades. Este ejemplo ilustra cómo adaptar la aplicación de plantilla a sus necesidades. Dada la estructura actual de la aplicación de plantilla, no es necesario realizar este cambio.

La aplicación de plantilla proporciona un interruptor que simula el dispositivo sin conexión. Este interruptor permite probar rápidamente la sincronización del dispositivo, simulando que el usuario no tiene conexión a internet. Sin embargo, es probable que este interruptor se elimine en una aplicación de producción.

Nota

Consulte el inicio rápido

Si prefieres explorar por tu cuenta en lugar de seguir un tutorial guiado, consulta la Guía de inicio rápido de React Native. Incluye ejemplos de código copiables y la información esencial necesaria para configurar una aplicación React Native con Atlas Device Sync.

  • Debes configurar tu entorno local para el desarrollo con React Native antes de comenzar este tutorial. Para obtener instrucciones detalladas, consulta "Configuración del entorno de desarrollo" en la documentación de React Native.

Este tutorial se basa en la aplicación de plantilla de sincronización flexible del SDK de React Native, denominada react-native.todo.flex. Comenzamos con la aplicación predeterminada y creamos nuevas funciones a partir de ella.

Para obtener más información sobre las aplicaciones de plantilla, consulte Aplicaciones de plantilla.

Si aún no tiene una cuenta Atlas, regístrese para implementar una aplicación de plantilla.

Siga el procedimiento descrito en la guía Crear una aplicación de servicios de aplicaciones y seleccione Create App from TemplateSeleccione la plantilla Real-time Sync. Esto crea una aplicación de Servicios de Aplicaciones preconfigurada para usarla con uno de los clientes de la plantilla de Sincronización de Dispositivos.

Después de crear una aplicación de plantilla, la interfaz de usuario muestra un modal con la etiqueta Get the Front-end Code for your Template. Este modal proporciona instrucciones para descargar el código del cliente de la aplicación de plantilla como un archivo .zip o usar la CLI de App Services para obtener el cliente.

Después de seleccionar el método .zip o la CLI de App Services, siga las instrucciones en pantalla para obtener el código de cliente. Para este tutorial, seleccione el código de cliente JavaScript (React Native).

Nota

La utilidad ZIP predeterminada de Windows podría mostrar el archivo .zip vacío. Si esto ocurre, use un programa de compresión de terceros disponible.

El comando de creación de aplicaciones appservices configura el backend y crea una aplicación de plantilla React Native para que la uses como base para este tutorial.

Ejecute el siguiente comando en una ventana de terminal para crear una aplicación llamada "MyTutorialApp" que se implementa en la región US-VA con su entorno configurado en "desarrollo" (en lugar de producción o control de calidad).

appservices app create \
--name MyTutorialApp \
--template react-native.todo.flex \
--deployment-model global \
--environment development

El comando crea un nuevo directorio en su ruta actual con el mismo nombre que el valor del indicador --name.

Puedes bifurcar y clonar un repositorio de GitHub que contenga el código del cliente de Device Sync. El código del cliente de React Native está disponible en https://github.com/mongodb/template-app-react-native-todo.

Si usa este proceso para obtener el código del cliente, debe crear una aplicación de plantilla para usarla con el cliente. Siga las instrucciones de "Crear una aplicación de plantilla" para usar la interfaz de usuario de Atlas App Services, la CLI de App Services o la API de administración para crear una aplicación de plantilla de Device Sync.

Utilice los siguientes pasos para poner en funcionamiento la aplicación de plantilla en su computadora:

1

En tu terminal, ve al directorio que contiene el código del cliente. Si creaste la aplicación con la CLI de App Services, ve a MyTutorialApp/react-native.todo.flex. De lo contrario, ve a la raíz del proyecto descargado o clonado. Luego, ejecuta los siguientes comandos para instalar las dependencias de la aplicación:

npm install

Para compilar y ejecutar la aplicación en un dispositivo o simulador iOS, instale las dependencias de iOS adicionales con CocoaPods.

cd ios
npx pod-install
2

En este punto, deberías tener una aplicación React Native completamente funcional que pueda ejecutarse en iOS, Android o ambos.

Si encuentras un error u otro problema, asegúrate de que tu entorno React Native esté configurado correctamente. Consulta la guía oficial de React Native sobre configuración del entorno de desarrollo. Sigue todos los pasos para tu SO de desarrollo y tu SO objetivo.

Para asegurarse de que todo funcione en iOS, cree la aplicación y ejecútela en un simulador de iOS:

npm run ios

Para asegurarse de que todo funciona en Android:

  1. Inicia un emulador de Android. Consulta "Ejecutar aplicaciones en el emulador de Android" para obtener más información.

  2. Construye la aplicación en el emulador:

    npm run android

    Un error común es Error: spawn ./gradlew EACCES. Esto significa que los permisos del archivo del proyecto no son los adecuados. En macOS, puedes solucionarlo introduciendo chmod 755 android/gradlew en tu terminal.

3

Al finalizar la compilación, deberías tener una aplicación funcional ejecutándose en tu simulador. En la aplicación, registra una nueva cuenta y prueba las funciones:

  • Añade algunos elementos por hacer a la lista.

  • Presione la casilla de verificación en uno o dos elementos para marcarlos como completados.

  • Presione la X en un elemento para eliminarlo de la lista.

  • Active la conectividad a Internet en la aplicación para simular el modo sin conexión.

Si te conectas a tu clúster Atlas y consultas la colección todo.Item, podrás ver los datos de tu aplicación. Mientras la aplicación React Native no esté en modo sin conexión, los nuevos datos y cambios se sincronizan automáticamente con la colección todo.Item.

Tip

Para saber cómo conectarse a su clúster Atlas, consulte Conectarse a un clúster Atlas.

De igual forma, cualquier cambio en la colección se sincroniza automáticamente con la app React Native. Intenta cambiar el estado de finalización de un elemento en tu clúster: la app React Native se actualizará automáticamente con el nuevo valor siempre que haya una conexión de red disponible.

Tip

Para obtener más información sobre cómo actualizar datos en su clúster, consulte Actualizar documentos.

Ahora que tienes la aplicación de plantilla ejecutándose, analicemos el código para ver con qué estamos trabajando.

La aplicación de plantilla incluye una aplicación de Servicios de Aplicaciones completamente configurada en el directorio backend. Tiene un valor appId único en atlasConfig.json que las aplicaciones cliente usan para conectarse.

También incluye las siguientes configuraciones predefinidas:

  • Una fuente de datos vinculada a su clúster Atlas.

  • Un modelo de datos para la colección todo.Item que coincide con la clase Item en la aplicación React Native.

  • Un proveedor de autenticación que permite a los usuarios registrarse e iniciar sesión en su aplicación con un correo electrónico y una contraseña.

  • Una configuración de sincronización flexible con un solo rol de sesión que permite a los usuarios leer y escribir sus propios elementos y ver los elementos de otros usuarios.

La aplicación React Native es un cliente móvil completamente configurado que puede ejecutarse en dispositivos iOS y Android.

La aplicación utiliza la biblioteca @realm/react. Esta biblioteca incluye ganchos y componentes de React que optimizan el trabajo con el backend de Atlas y la base de datos de Realm.

La aplicación contiene algunos archivos de configuración y directorios, pero puedes ignorarlos a menos que quieras personalizarla. Para este tutorial, debes estar familiarizado con los componentes de React en el directorio source/:

Nombre del archivo
Descripción

ItemSchema.tsx

La clase Item, incluido su modelo de datos de objetos. Importamos esta clase en AppWrapper.tsx para incluirla en el esquema general de Realm de la aplicación.

AppWrapper.tsx

Este es el componente raíz de la aplicación. Funciona como un componente contenedor y contiene todos los proveedores @realm/react. Aquí se configura el dominio y la conexión con el backend de Atlas.

App.tsx

La mayor parte de la funcionalidad de la aplicación se encuentra en este componente y sus componentes secundarios. Dado que los proveedores @realm/react están integrados en este componente, puede acceder a una instancia de su backend Atlas, a objetos de usuario e interactuar con la base de datos de Realm.

WelcomeView.tsx

El formulario de registro e inicio de sesión de usuario que los usuarios ven cuando abren la aplicación por primera vez.

ItemListView.tsx

La aplicación principal de listas de tareas con la que interactúan los usuarios tras iniciar sesión. Consulta objetos Item de Realm y los muestra en una lista. También incluye el código para crear nuevos objetos Item y almacenarlos en Realm.

CreateToDoPrompt.tsx

Un formulario de interfaz de usuario que nos permite introducir datos para nuevos objetos Item. El código que crea los nuevos objetos está en ItemListView.tsx.

LogoutButton.tsx

Un botón reutilizable que cierra la sesión de un usuario autenticado.

OfflineModeButton.tsx

Un botón reutilizable que simula un modo fuera de línea pausando y reanudando el Reino actual syncSession.

Ahora que está más familiarizado con lo que ya se proporciona en la aplicación de plantilla, escribamos algo de código para implementar una nueva función.

En este tutorial, añadiremos una nueva propiedad priority a los objetos Item. Esto nos permitirá organizar las tareas pendientes según su importancia y centrarnos solo en las más importantes.

1

Queremos permitir un número reducido de niveles de prioridad con nombre y ordenarlos fácilmente. Para ello, usaremos una función auxiliar para definir un objeto enum que asigna un conjunto de nombres de niveles ordenados a un entero que representa su prioridad.

Agregue el siguiente código directamente debajo de las declaraciones de importación en source/ItemSchema.tsx:

function createEnum(arr) {
arr.forEach((p, i) => arr[p] = i);
return arr;
}
// Priority.High === 1
// Priority[Priority.High] === "High"
export const Priority = createEnum([
"Severe",
"High",
"Medium",
"Low",
])

Los niveles de prioridad en enum se ordenan de mayor a menor importancia. El valor del índice correspondiente a cada nivel aumenta del más importante, Priority[0], al menos importante, Priority[3]. Esto significa que un nivel de prioridad más alto (es decir, más importante) tiene un valor de índice más bajo.

2

Ahora tenemos un enum que define los posibles valores del campo priority. Sin embargo, aún debemos definir el campo priority en la clase Item.

Agregue las siguientes líneas a su código en source/ItemSchema.tsx para agregar priority al modelo de datos Item:

fuente/ItemSchema.tsx
export class Item extends Realm.Object<Item> {
_id!: BSON.ObjectId;
isComplete!: boolean;
summary!: string;
owner_id!: string;
priority!: string;
static schema: Realm.ObjectSchema = {
name: 'Item',
primaryKey: '_id',
properties: {
// This allows us to automatically generate a unique _id for each Item
_id: {type: 'objectId', default: () => new BSON.ObjectId()},
// All todo items will default to incomplete
isComplete: {type: 'bool', default: false},
summary: 'string',
owner_id: 'string',
priority: {
// Store the index value of the Priority enum rather than the name
type: 'int',
default: Priority.High
},
},
};
}

Nota

¿Por qué no se rompió la sincronización?

En este punto, tu modelo Item de React Native y su esquema correspondiente en tu aplicación de App Services ya no coinciden. ¡No te preocupes!

Añadir una propiedad a un objeto Realm no supone un cambio drástico y, por lo tanto, no requiere restablecer el cliente. La aplicación de plantilla tiene habilitado el modo de desarrollo, por lo que los cambios en el objeto Realm del cliente se reflejan en el esquema del servidor. Para obtener más información, consulte Modo de desarrollo y Actualizar el modelo de datos.

3

El modelo de datos de tu aplicación ahora incluye un priority por cada objeto Item. Actualicemos la interfaz de usuario de la aplicación para que puedas elegir un valor de prioridad al añadir una nueva tarea a la lista.

Primero, instalaremos una biblioteca externa para implementar el componente selector de prioridad. Ejecute lo siguiente en su terminal, dentro de la raíz del proyecto:

npm install @react-native-picker/picker

Si está compilando para iOS, asegúrese de vincular los Cocoapods asociados después de haber instalado el paquete:

npx pod-install

Tip

Es posible que tengas que reconstruir tu aplicación después de instalarla. Para ello, detén el empaquetador de tu proyecto y ejecuta el comando de compilación:

npm run ios
npm run android

Ahora que el paquete está completamente instalado, actualicemos el nuevo componente de solicitud de creación de tareas pendientes para usar el selector.

Agregue las siguientes importaciones a la parte superior de source/CreateToDoPrompt.tsx:

import {Picker} from '@react-native-picker/picker';
import {Priority} from './ItemSchema';

Luego, modifique el componente CreateToDoPrompt:

  • Agregar priority a la definición de propiedades onSubmit()

  • Realizar un seguimiento de priority en un gancho de estado

  • Conecte el estado al componente Picker que importó

  • Pase priority al controlador onSubmit()

fuente/CreateToDoPrompt.tsx
type Props = {
onSubmit(args: {summary: string; priority: string;}): void;
};
export function CreateToDoPrompt(props: Props): React.ReactElement<Props> {
const {onSubmit} = props;
const [summary, setSummary] = useState('');
const [priority, setPriority] = useState(Priority.High);
return (
<View style={styles.modalWrapper}>
<Text h4 style={styles.addItemTitle}>
Add To-Do Item
</Text>
<Input
placeholder="What do you want to do?"
onChangeText={(text: string) => setSummary(text)}
autoCompleteType={undefined}
/>
<Picker
style={{width: '80%'}}
selectedValue={priority}
onValueChange={value => setPriority(value)}>
{Priority.map(priority => (
<Picker.Item
key={priority}
label={priority}
value={Priority[priority]}
/>
))}
</Picker>
<Button
title="Save"
buttonStyle={styles.saveButton}
onPress={() => onSubmit({summary, priority})}
/>
</View>
);
}

En source/ItemListView.tsx, modifique la función createItem() para aceptar y usar priority:

fuente/ItemListView.tsx
const createItem = useCallback(
({summary, priority}: {summary: string, priority: string}) => {
realm.write(() => {
return new Item(realm, {
summary,
owner_id: user?.id,
priority
});
});
},
[realm, user],
);

Luego, modifique el controlador de envío de creación de tareas para aceptar el nivel priority y pasarlo a createItem():

fuente/ItemListView.tsx
<CreateToDoPrompt
onSubmit={({summary, priority}) => {
setShowNewItemOverlay(false);
createItem({summary, priority});
}}
/>

Por último, modifique la plantilla de elementos de lista para representar las tareas pendientes priority antes de summary:

fuente/ItemListView.tsx
<ListItem
key={`${item._id}`}
bottomDivider
topDivider
hasTVPreferredFocus={undefined}
tvParallaxProperties={undefined}>
<Text>{item.priority}</Text>
<ListItem.Title style={styles.itemTitle}>
{item.summary}
</ListItem.Title>
<ListItem.Subtitle style={styles.itemSubtitle}>
{item.owner_id === user?.id ? '(mine)' : ''}
</ListItem.Subtitle>
<ListItem.CheckBox
checked={item.isComplete}
checkedColor={COLORS.primary}
iconType="material"
checkedIcon="check-box"
uncheckedIcon="check-box-outline-blank"
onPress={() => toggleItemIsComplete(item._id)}
/>
<Button
type="clear"
onPress={() => deleteItem(item._id)}
icon={
<Icon
type="material"
name="clear"
size={12}
color="#979797"
tvParallaxProperties={undefined}
/>
}
/>
</ListItem>
4

Su aplicación ahora debería permitir a los usuarios establecer un nivel de prioridad para los nuevos elementos pendientes.

Reconstruye la aplicación y ábrela. Agrega nuevas tareas para confirmar que puedes elegir un nivel de prioridad y que la lista muestra la prioridad de cada tarea.

El protocolo Device Sync utiliza un modelo flexible donde cada cliente de sincronización utiliza una consulta RQL estándar para seleccionar un subconjunto de datos de la aplicación y luego se suscribe a él. Esto extrae automáticamente la última versión de todos los datos del subconjunto al dispositivo y sincroniza los cambios entre dispositivos.

Por ejemplo, la aplicación de plantilla que estás usando tiene la siguiente suscripción incorporada a los artículos que posee el usuario actual:

fuente/ItemListView.tsx
realm.subscriptions.update(mutableSubs => {
mutableSubs.removeByName(itemSubscriptionName);
mutableSubs.add(
realm.objects(Item).filtered(`owner_id == "${user?.id}"`),
{name: ownItemsSubscriptionName},
);
});

Puedes personalizar la suscripción durante la ejecución para sincronizar solo los datos que tu aplicación necesita. Añadamos una función para demostrar cómo.

Para este tutorial, agregaremos un botón que nos permite alternar entre dos modos: uno en el que la aplicación sincroniza todos los elementos pendientes y otro en el que solo sincroniza los importantes con un priority de Alto o Grave.

1

Primero, agregue un gancho useState() al componente ItemListView para realizar un seguimiento del modo actual:

Vista de lista de artículos.tsx
const [showImportantOnly, setShowImportantOnly] = useState(false);

Luego, agregue un nuevo botón que cambie el modo al final de la lista de tareas pendientes, después de <ListItem>:

fuente/ItemListView.tsx
<Button
title={showImportantOnly ? 'Show All' : 'Show Important Only'}
buttonStyle={{
...styles.addToDoButton,
backgroundColor: showImportantOnly ? '#00A35C' : '#FFC010',
}}
onPress={() => setShowImportantOnly(showImportantOnly => !showImportantOnly)}
/>
2

En este punto, la aplicación puede cambiar de modo en la interfaz de usuario, pero no hemos hecho nada más, por lo que los modos son funcionalmente idénticos. Actualicemos la suscripción de sincronización para que solo sincronice los datos relevantes para el modo actual.

En el primer useEffect del componente ItemListView, agregue código que verifique el modo actual y agregue un filtro priority adicional a la consulta si el modo showImportantOnly está activo:

fuente/ItemListView.tsx
useEffect(() => {
if (showAllItems) {
realm.subscriptions.update(mutableSubs => {
mutableSubs.removeByName(ownItemsSubscriptionName);
mutableSubs.add(realm.objects(Item), {name: itemSubscriptionName});
});
} else if (showImportantOnly) {
realm.subscriptions.update(mutableSubs => {
mutableSubs.removeByName(itemSubscriptionName);
mutableSubs.add(
realm.objects(Item).filtered(`owner_id == "${user?.id}" && priority <= 1`),
{name: ownItemsSubscriptionName},
);
});
} else {
realm.subscriptions.update(mutableSubs => {
mutableSubs.removeByName(itemSubscriptionName);
mutableSubs.add(
realm.objects(Item).filtered(`owner_id == "${user?.id}"`),
{name: ownItemsSubscriptionName},
);
});
}
}, [realm, user, showAllItems, showImportantOnly]);

Importante

No olvide agregar showImportantOnly a la lista de dependencias en el segundo argumento de useEffect.

3

Su aplicación ahora está configurada para modificar su suscripción de sincronización según el modo actual.

Reconstruye y ejecuta la aplicación para asegurarte de que todo funciona correctamente. Deberías poder crear, completar y eliminar tareas pendientes, así como alternar entre ver todas las tareas y solo las importantes.

Tip

Cambiar suscripciones con el modo de desarrollador habilitado

En este tutorial, al cambiar la suscripción y la consulta en el campo de prioridad por primera vez, este se añade automáticamente a la sincronización de dispositivos Collection Queryable Fields. Esto se debe a que la aplicación de plantilla tiene el modo de desarrollo habilitado de forma predeterminada. Si el modo de desarrollo no estuviera habilitado, tendría que añadir manualmente el campo como consultable para usarlo en una consulta de sincronización del lado del cliente.

Para obtener más información, consulte Campos consultables.

Nota

Compartir comentarios

¿Cómo te fue? Usa el Rate this page widget en la parte inferior derecha de la página para evaluar su efectividad. O reporta un problema en el repositorio de GitHub si tuviste algún problema.

Next

¿Qué son los servicios de aplicación Atlas?