Las funciones en la nube de los mini programas de WeChat simplifican enormemente el desarrollo al manejar la lógica del lado del servidor. Eilminan la necesidad de configurar y mantener un servidor tradicional, lo cual es una ventaja económica significativa para desarrolladores individuales o proyectos con escala moderada.
Obtención del número de teléfono del usuario
Antes de las funciones en la nube, descifrar los datos sensibles del usuario requería un proceso de backend personalizado. Ahora, con la integración del SDK de WeChat Cloud, el decsifrado se gestiona de forma automática al enviar el cloudID a la función.
A continuación, se muestra un ejemplo de implementación refactorizado:
// Archivo de entrada de la función en la nube: obtenerTelefono.js
const wxSdk = require('wx-server-sdk');
wxSdk.init({
env: wxSdk.DYNAMIC_CURRENT_ENV
});
// Función principal de la nube
exports.main = async (payload, ctx) => {
const contexto = wxSdk.getWXContext();
// Extraer el número de teléfono de los datos ya descifrados por el SDK
const telefono = payload.datosTelefono.data.phoneNumber;
return {
telefono,
usuarioId: contexto.OPENID,
appId: contexto.APPID
};
};
Desde el mini programa, se invoca la función manejando el evento del botón de obtención de teléfono:
// En el manejador del evento bindgetphonenumber
async handleTelefono(e) {
if (!e.detail.cloudID) {
wx.showToast({ title: 'Autorización denegada', icon: 'none' });
return;
}
try {
wx.showLoading({ title: 'Procesando...' });
const res = await wx.cloud.callFunction({
name: 'obtenerTelefono',
data: {
datosTelefono: wx.cloud.CloudID(e.detail.cloudID)
}
});
const numTelefono = res.result.telefono;
console.log('Teléfono obtenido:', numTelefono);
// Proceder con el registro o lógica siguiente
} catch (error) {
console.error('Error al obtener teléfono:', error);
} finally {
wx.hideLoading();
}
}
Operaciones CRUD con la base de datos en la nube
La base de datos en la nube de WeChat utiliza un esquema flexible, lo que permite crear funciones genéricas para operaciones comunes. El siguiente ejemplo crea una única función en la nube que actúa como un controlador para diferentes acciones en la base de datos.
// Archivo de entrada: controladorDb.js
const wxSdk = require('wx-server-sdk');
wxSdk.init();
const db = wxSdk.database();
const _ = db.command; // Comandos de consulta avanzados
const MAX_REGISTROS = 100;
// Función auxiliar para insertar documentos
async function crearDocumento(coleccion, datos) {
return await db.collection(coleccion).add({ data: datos });
}
// Función auxiliar para obtener todos los documentos con paginación
async function obtenerDocumentos(coleccion) {
const { total } = await db.collection(coleccion).count();
const ciclos = Math.ceil(total / MAX_REGISTROS);
const tareasLectura = [];
for (let i = 0; i < ciclos; i++) {
const consulta = db.collection(coleccion)
.skip(i * MAX_REGISTROS)
.limit(MAX_REGISTROS)
.get();
tareasLectura.push(consulta);
}
const resultados = await Promise.all(tareasLectura);
return resultados.reduce((acumulado, respuestaActual) => ({
data: acumulado.data.concat(respuestaActual.data),
errMsg: acumulado.errMsg
}), { data: [], errMsg: '' });
}
// Función auxiliar para buscar documentos por criterio
async function buscarDocumentos(coleccion, criterio) {
return await db.collection(coleccion).where(criterio).get();
}
// Función auxiliar para actualizar un documento
async function modificarDocumento(coleccion, idDocumento, nuevosDatos) {
return await db.collection(coleccion).doc(idDocumento).update({ data: nuevosDatos });
}
// Función auxiliar para eliminar un documento
async function borrarDocumento(coleccion, idDocumento) {
return await db.collection(coleccion).doc(idDocumento).remove();
}
// Función principal de la nube
exports.main = async (evento) => {
const { accion, coleccion, datos, criterio, documentoId } = evento;
switch (accion) {
case 'INSERTAR':
return await crearDocumento(coleccion, datos);
case 'LEER_TODO':
return await obtenerDocumentos(coleccion);
case 'BUSCAR':
return await buscarDocumentos(coleccion, criterio);
case 'ACTUALIZAR':
return await modificarDocumento(coleccion, documentoId, datos);
case 'ELIMINAR':
return await borrarDocumento(coleccion, documentoId);
default:
return { errCode: -1, errMsg: 'Acción no reconocida' };
}
};
Ejemplo de uso desde el front end del mini programa para interactuar con esta función:
// Obtener todos los registros de una colección 'mensajes'
wx.cloud.callFunction({
name: 'controladorDb',
data: {
accion: 'LEER_TODO',
coleccion: 'mensajes'
}
}).then(res => {
const listaMensajes = res.result.data.map(mensaje => ({
id: mensaje._id,
texto: mensaje.contenido,
autor: mensaje.autorId,
fecha: new Date(mensaje.timestamp).toLocaleString()
}));
this.setData({ listaMensajes });
});
// Insertar un nuevo registro en la colección 'valoraciones'
const nuevaValoracion = {
puntuacion: 5,
comentario: 'Excelente servicio',
fechaCreacion: db.serverDate() // Usa el timestamp del servidor
};
wx.cloud.callFunction({
name: 'controladorDb',
data: {
accion: 'INSERTAR',
coleccion: 'valoraciones',
datos: nuevaValoracion
}
}).then(() => {
wx.showToast({ title: 'Valoración registrada' });
}).catch(console.error);