DevAces
¿Como crear una tienda en línea con Snipcart, Angular y Firebase?

¿Como crear una tienda en línea con Snipcart, Angular y Firebase?

¡Lo has logrado! Has logrado construir un negocio y ahora quieres hacerlo crecer. ¿Pero cómo? Una tienda en línea es tu mejor opción para hacer crecer tu negocio, ya que tus clientes podrán conseguir tus productos no importando el día o la hora, sin que tengas que mover un solo dedo. ¿Y cómo creo una tienda en línea? Pues existen muchas formas de crear una tienda en línea, pero en este artículo vamos a integrar Snipcart con una aplicación de Angular.

Requisitos

Para seguir este ejemplo debes de estar familiarizado con el framework Angular, además de tener instalada la herramienta CLI de Angular en tu computadora. También es recomendado saber manejar Firebase, aunque solo lo vamos a ocupar para almacenar la información de nuestros productos.

Iniciando el proyecto

Primero vamos a crear la aplicación de Angular. Abrimos la terminal en la carpeta que elijan (en el escritorio, por ejemplo) y ejecutamos el comando ng new snipcart-angular. Ya creada nuestra aplicación de Angular podemos ejecutar el comando ng serve -o para estar al pendiente de los cambios que le hagamos a nuestra aplicación.

De manera opcional, puedes hacer uso de nuestro proyecto de ejemplo para seguir este post, el cual se encuentra en el siguiente repositorio en GitHub.

Ahora vamos a crear nuestro proyecto de Firebase. Primero entramos a la consola de Firebase, le damos en añadir proyecto y seguimos los pasos que nos marca Firebase.

Crear proyecto en la consola de Firebase

Una vez creado nuestro proyecto vamos a seleccionar Database, debajo de desarrollo en el menú lateral. No vamos a usar la opción de Cloud Firestore, vamos a bajar hasta la parte de Realtime Database (RTDB) y damos clic en “Crear base de datos”. ¿Por qué no usamos Cloud Firestore para este proyecto? Porque la Realtime Database guarda la información en formato JSON y cuenta con una API de REST para realizar consultas, lo cual vamos a ocupar más adelante para la integración con Snipcart.

Seleccionar Realtime Database

No necesitamos instalar dependencias de Firebase en nuestra aplicación de Angular, ya que vamos a usar la API de REST de la RTDB.

Instalando Snipcart

Snipcart es una plataforma de comercio en línea sumamente fácil de integrar a cualquier sitio web. Esta plataforma incluye funciones como un dashboard para manejar todas tus ordenes, productos, inventario, etc. Y te permite manejar tus pagos con Paypal, Stripe, entre otros. Para conocer más sobre Snipcart visita su sitio web.

Para empezar a trabajar con Snipcart lo primero que hay que hacer es crear una cuenta. Una vez hecho esto entrarás al dashboard de Snipcart.

Dashboard de Snipcart

Para integrar nuestra aplicación de Angular con Snipcart primero necesitamos nuestra llave de API de Snipcart. Ojo que la llave de API del ambiente de pruebas es diferente a la llave de API de producción, por lo que la tienes que cambiar cuando esté lista tu tienda en línea. La llave de API se encuentra en el menú lateral derecho → Cuentas → Llaves de API. En esta página encontraremos un snippet de código como este:

<link rel="stylesheet" href="https://cdn.snipcart.com/themes/v3.0.9/default/snipcart.css" />

<div id="snipcart" data-api-key="YOUR-API-KEY" hidden></div>

<script src="https://cdn.snipcart.com/themes/v3.0.9/default/snipcart.js"></script>

Este snippet de código lo copiamos y lo vamos a pegar dentro del index.html de nuestra aplicación de Angular. El CSS lo copiamos en el head y el resto al final del body. Con esto estamos listos para trabajar con Snipcart en nuestra aplicación.

Definiendo nuestros productos

Ahora tenemos que definir nuestros productos y que puedan ser ocupados por Snipcart. Para conseguir esto necesitamos agregar diferentes atributos al elemento HTML que será nuestro botón de compra. La documentación de Snipcart proporciona este ejemplo.

<button class="snipcart-add-item"
  data-item-id="starry-night"
  data-item-price="79.99"
  data-item-url="/paintings/starry-night"
  data-item-description="High-quality replica of The Starry Night by the Dutch post-impressionist painter Vincent van Gogh."
  data-item-image="/assets/images/starry-night.jpg"
  data-item-name="The Starry Night">
    Add to cart
</button>

Existen otros atributos definidos por Snipcart pero los atributos de ID, nombre, precio, URL, descripción e imagen son requeridos, por lo que necesitamos que nuestros productos contengan estos campos.

Lo que vamos a hacer es almacenar la información de nuestros productos en la RTDB y por medio de su API de REST traeremos esa información a nuestra aplicación de Angular. Entonces, primero tenemos que agregar nuestros productos a la RTDB ya sea manualmente o importando un archivo JSON (recomendado). Es muy importante que nuestros productos tengan una estructura como la siguiente para que correspondan con la definición de productos de Snipcart.

[
  {
    "category": "Category",
    "description": "Product 1 description",
    "id": "P001",
    "image": "image-url/product1.jpg",
    "name": "Product 1",
    "price": 1000,
    "url": "https://YOUR-FIREBASE-PROJECT.firebaseio.com/products.json"
  },
  ...
]

Si te preguntas de donde salió la URL https://YOUR-FIREBASE-PROJECT.firebaseio.com/products.json, es parte del uso de la API de REST de la RTDB. De acuerdo con la documentación

Podemos usar cualquier URL de Firebase Realtime Database como un extremo de REST. Todo lo que tenemos que hacer es anexar .json al final de la URL...

Esta URL va a ser la misma para todos los productos definidos. Además, asegúrate de que cualquier persona tenga acceso de lectura a tus productos utilizando las reglas de la RTDB.

Desplegando nuestros productos en la aplicación de Angular

Ya que tenemos nuestros productos almacenados en la RTDB es momento de usarlos en nuestra aplicación de Angular. Para empezar, abrimos el app.module.ts de nuestra aplicación e importamos el HttpClientModule en el arreglo de imports, de esta manera.

// Otras importaciones
...
// Importacion del HttpClientModule
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...,
    HttpClientModule
  ],
  ...
})
export class AppModule { }

Ahora abrimos el app.component.ts. Primero podemos definir una interfaz de Typescript fuera de la clase para trabajar más fácilmente con nuestros productos como se muestra a continuación, pero este paso es opcional.

// Interfaz de productos
interface Product {
    id: string;
    category: string;
    name: string;
    price: number;
    url: string;
    description: string;
    image: string;
}

Seguimos en el app.component.ts y dentro de la clase definimos la propiedad products$: Observable<Product[]> e inyectamos en el constructor el HttpClient, asegurándonos de importar lo necesario. Ahora necesitamos definir un método que obtenga los productos de la RTDB, así:

// Método para obtener productos de la RTDB
getProducts() {
  return this.http.get<Product[]>('https://YOUR-FIREBASE-PROJECT.firebaseio.com/products.json');
}

Y dentro del método ngOnInit vamos a llamar al método getProducts para inicializar nuestra propiedad products$, de esta manera:

ngOnInit() {
  this.products$ = this.getProducts();
}

Después, abrimos el app.component.html para mostrar nuestros productos. Hay que recordar el ejemplo del botón de compras de Snipcart, sin embargo, como estamos trabajando con Angular lo vamos a hacer de manera dinámica. Puedes elegir la presentación que quieras para mostrar tus productos, pero lo importante para trabajar con Snipcart es ese botón de compras.

<div *ngFor="let product of products$ | async">
  ...
  <button class="snipcart-add-item"
    [attr.data-item-id]="product.id"
    [attr.data-item-price]="product.price"
    [attr.data-item-url]="product.url"
    [attr.data-item-description]="product.description"
    [attr.data-item-image]="product.image"
    [attr.data-item-name]="product.name"
    [attr.data-item-categories]="product.category">
      Comprar ahora
  </button>
</div>

Como explicación al snippet anterior, ocupamos el pipe async para desenvolver nuestra propiedad de products$ que es un observable. Al mismo tiempo usamos la directiva *ng-for para crear un elemento por cada producto. Para el botón de compras vinculamos los atributos requeridos por Snipcart con las propiedades de nuestros productos.

Si has trabajado con Angular anteriormente quizás te preguntas ¿por qué no solo ocupar [data-item-x]="product.x"? Esto te va a arrojar un error, ya que Angular no reconoce data-item-x como un atributo válido del elemento <button>, por lo que es necesario hacerlo de la forma en que está el snippet.

Por último, para acceder al carrito de compras y realizar una orden, Snipcart requiere un elemento como el siguiente:

<button class="snipcart-checkout">Click here to checkout</button>

Este botón lo puedes agregar en el encabezado de tu aplicación de Angular.

Validación de órdenes de compra

Cada vez que se realiza una orden de compra con Snipcart, la plataforma realiza una validación de dicha orden. Esta validación toma en cuenta el atributo URL del producto y realiza una petición HTTP a esta URL. Esta URL puede ser el dominio de tu sitio web, Snipcart verificará que la información de la orden de compra corresponda con la información en tu sitio web. Sin embargo, como estamos trabajando con una aplicación de Angular, esta validación siempre va a fallar, ya que nuestra aplicación se renderiza en el lado del cliente.

Hay varias opciones para poder validar las órdenes de compra de nuestra aplicación de Angular, como usar Angular Universal para renderizar nuestra aplicación del lado del servidor. Pero vamos a hacerlo de una manera más sencilla. La URL del producto también puede ser la dirección de un archivo JSON. En este caso, Snipcart verificará que la información de la orden de compra corresponda con la información del archivo JSON. Esta es la razón principal por la que hemos estado trabajando con la RTDB, una vez más podemos aprovechar su API de REST para conseguir esta validación.

Vamos a entrar a nuestro Dashboard de Snipcart y vamos a ir al menú lateral derecho → Dominios & URLs. Aquí vamos a agregar nuestro dominio principal en la sección marcada como "DEFAULT WEBSITE DOMAIN" y en la sección "OTHER DOMAINS & SUBDOMAINS" vamos a agregar la URL de nuestros productos (YOUR-FIREBASE-PROJECT.firebaseio.com/products.json). Asegúrate de escoger la opción HTTPS para agregar esta última.

Manejar dominios en Snipcart

En este punto puedes probar tu tienda en línea y asegurarte que todo funciona. Con esto ya tenemos lista nuestra tienda en línea con Snipcart, Angular y Firebase. Recuerda que tenemos disponible un proyecto de ejemplo en este repositorio, por si necesitas ayuda extra.


Si necesitas ayuda para crear tu tienda en línea, en DevAces somos expertos en la creación de sitios web profesionales, tiendas en línea y marketing digital. ¡Acércate a nosotros y crearemos la solución digital que más se acomode a tu negocio y presupuesto!

Da clic aquí para conocer nuestros servicios y contactarnos.

No olvides darle like a nuestra página en Facebook para mantenerte al tanto de nuestras publicaciones.

Checa nuestra última publicación para saber por qué es importante que tu negocio tenga una presencia en línea.