Firebase: No existe método de facturación asociado con las cuenta

lunes, octubre 12th, 2020

Anteriormente no era necesario tener un método de facturación asociado a tu cuenta para poder hacer deploys de funciones Firebase, el plan gratuito era suficiente. A partir de la migración a nodejs 10.00 de las funciones Firebase de Cloud Functions, es necesario que cuentes con un método de facturación válido. Es posible que recibas un mensaje como el siguiente

HTTP Error: 400, Billing account for project '68817281782' is not found. Billing must be enabled for activation of service(s) 'cloudbuild.googleapis.com,containerregistry.googleapis.com' to proceed.

Para solventarlo simplemente debes cambiar tu plan y registrar tu método de pago en la consola de firebase, para que entiendas mejor lo que ha sucedido te dejo los 3 planes de facturación :

  1. Spark: gratuito, ideal para empezar con tu primera app
  2. Flame: por un cobro de 25 dls mensuales, podrías incrementar las cuotas de consumo, en número de transacciones por día.
  3. Blaze: aqui se te cobra por lo que consumes.

Atención : A partir de Enero de 2020 Google elimina el plan FLAME y quedan disponibles únicamente el plan Spark y Blaze activos, en principio esto no significaría gran diferencia si cuentas con un plan SPARK, a menos que tengas funciones de google deployadas en Google Cloud Function.

Si tienes funciones de Cloud Functions activa en tu proyecto debes migrar tus proyectos al plan Blaze. tus cuotas gratuitas se mantendrían disponibles y siempre que no las sobrepases no se te cobrará nada, aunque si debes contar con un medio de pago registrado, si es este tu caso debes hacer lo siguiente:

Las cuotas disponibles al momento de escribir este articulo octubre 2020 son las siguientes:

  • 2 Millones de invocaciones por mes
  • 400 mil GB- por segundo al mes
  • 200 mil CPU segundos al mes

Más información sobre los planes de facturación aqui

Cambiar el plan facturación de tu proyecto de firebase

Puedes cambiar el plan de facturación de tu proyecto dando click en la imagen

A continuación google te pedirá que selecciones el plan de uso Blaze

Firebase es parte de Google Cloud Platform que es la nube de servicios para desarrolladores de google, puesto que estas dos plataformas comparten los proyectos es necesario que configures en Google Cloud Platform la forma de pago.

ya puedes aceptar los términos del contrato

A continuación ya puedes ingresar los datos de tu tarjeta y tus datos de facturación, recuerda que esto es para tener una tarjeta de credito o debito asociada a Google Cloud Platform, pero todavía falta regresar a la consola de firebase y seleccionar el plan Blaze.

Dirigite a la consola de Firebase y selecciona el plan Blaze

Una buena idea es que configures una alerta de presupuesto para evitar que los gastos se te disparen desmedidamente ante un inesperado crecimiento en el uso de tu app

Si tienes dudas sobre el plan con que cuentas en este momento te sugiero que consultes en la configuración de tu proyecto, tal y como se indica en la imagen a continuación

Debes tener el Plan Blaze

Si tienes dudas sobre los planes de facturación y cuotas gratis te recomiendo visites el siguiente enlace

Planes de Facturación en Firebase

Una vez ya tienes tus plan de pagos establecido para tu proyecto puedes ejecutar el comando para el deploy de la función

firebase deploy --only functions


Crear un nuevo proyecto de Firebase

lunes, octubre 12th, 2020

Paso 1) Crear un proyecto nuevo de firebase de pruebas, aceptamos los términos del contrato y le damos continuar

Paso 2) Aceptar la configuración del google analitycs

Paso 3) seleccionar la ubicación de tu google analitycs

A continuación le damos click en crear proyecto

Paso 4) Configurar la primera aplicación en firebase, en nuestro caso para angular debemos seleccionar la opcion de aplicación web

Seleccionamos la opción de aplicación web

Seleccionamos las opciones de configurar un hosting para que podamos almacenar funciones y otros archivos necesarios

Si estuviéramos trabajando con un proyecto web, tendríamos que usar las librerías cargadas en los head de nuestro archivo HTML, pero en nuestro caso los ejemplos de este blog, se harán usando la librería de angularfire2. En esta parte solo le damos siguiente, si tu proyecto fuese en html directamente, si tendrías que copiar estas cabeceras.

Instala la CLI (Command Line Input) para trabajo con firebase, esta te servirá para que puedas ejecutar comandos de firebase directamente en la consola, recuerda que para hacerlo debe tener el manejador de paquetes npm, y la última versión de nodejs instalada en tu sistema operativo.

npm install -g firebase-tools

Ahora que ya tienes instalado la CLI de Firebase, puedes ejcutar comandos para inicio de sesión en firebase deployar en el hosting y otros comandos. Te dejo algunos a continuación:

firebase login 
firebase init 
firebase deploy 


Problemas al trabajar con firebase functions

lunes, octubre 12th, 2020

Puede que al momento de crear funciones de firebase, te de un error como el que sigue

Error: Failed to list Firebase projects. See firebase-debug.log for more info.

Si es ese el caso te recomiendo que revises el archivo firebase-debug.log en él puedes encontrar mayor información sobre los errores, pero un error común es que el token de inicio de sesión este desfasado, si es este tu caso, debes re logearte para poder trabajar con funciones

Tu archivo de firebase-debug.log mostrará algo como lo siguiente

Request had invalid authentication credentials.

Recuerda

Simplemente debes escribir el siguiente comando

firebase logout

Lo anterior te deslogeara para que puedas ingresar de nuevo, al hacerlo el token de inicio de sesión se refrescará

firebase login 

Al volver a logear se renovara el token de inicio de sesión y ya podrá ser posible seleccionar un proyecto existente, o bien crear uno nuevo.


Añadir un método de autenticación con Angular

miércoles, noviembre 6th, 2019

Para autenticarnos en una app de angular, debes importar dos librerías

import { AngularFireAuth } from '@angular/fire/auth';
import { auth } from 'firebase/app';

Lo mejor es crear un servicio que se encargue de la gestión del Login y Logout para lo cual debemos ejecutar el siguiente comando

ng generate service auto-usr --spec false 

En el servicio importamos las dos librerías anteriores y creamos uns propiedad user que contendrá la información que devuelva el google provider.

public user;

Ahora debemos instanciar el objeto auth

 constructor(public afAuth: AngularFireAuth) { }

A continuación se crean los dos métodos para loguearse y desloguearse

login() {
    this.afAuth.auth.signInWithPopup(new auth.GoogleAuthProvider());
    this.user=this.afAuth;
    console.log(this.user);
}
logout() {
    this.afAuth.auth.signOut();
}
  

El código completo del servicio queda así

import { Injectable } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import { auth } from 'firebase/app';

@Injectable({
  providedIn: 'root'
})
export class AutoUsrService {
  public user;
  
  constructor(public afAuth: AngularFireAuth) { }

  login() {
    this.afAuth.auth.signInWithPopup(new auth.GoogleAuthProvider());
    this.user=this.afAuth;
    console.log(this.user);
  }
  logout() {
    this.afAuth.auth.signOut();
  }
  
}

Plantilla de inicio

Ahora debemos importar el servicio al componente principal de la app, en este componente establecemos una condición que impida mostrar la información

import { AutoUsrService } from './auto-usr.service';

Y en el constructor creamos una instancia del servicio

 public  slAuthService:AutoUsrService

y luego los dos métodos que invoquen el login y el logout del servicio

login() {
    this.slAuthService.login();
  }
  logout() {
    this.slAuthService.logout();
  }

El código completo del componente principal queda así

import { Component } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';
import { AutoUsrService } from './auto-usr.service';
import { Observable } from 'rxjs';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';
  items: Observable<any[]>;
  constructor(db: AngularFirestore, public  slAuthService:AutoUsrService) {
    this.items = db.collection('items').valueChanges();
  }

  login() {
    this.slAuthService.login();
  }
  logout() {
    this.slAuthService.logout();
  }
}

Creando la plantilla html del componente

Para definir una plantilla en base al estado del usuario se usará la directiva *ngIf de este modo si el usuario no esta logueado mostrará el botón para hacerlo.

Caso contrario si el usuario ya está logueado mostrará un botón de logout

<div *ngIf="slAuthService.afAuth.user | async as user; else showLogin"> 
  <div class="container">     
      <p>Bienvenido {{ user.displayName }}</p>
      <button (click)="logout()" class="btn btn-danger">Logout</button> 

      <ul>
        <li class="text" *ngFor="let item of items | async">
          {{item.name}}
        </li>
      </ul>
      <!-- <app-login></app-login>
       -->
      <router-outlet></router-outlet>     
  </div>
</div>

<ng-template #showLogin>
<div class="container">  
  <div class="row">
      <div class="col-md-12 col-md-offset-2">
          <br>
          <p>Debes Logearte para acceder al sistema.</p>
          <button (click)="login()" class="btn btn-danger">Logearte con una cuenta Google</button>
          <p>
              <small>debes contar con una cuenta de google para poder usar el sistema</small>
          </p>
      </div>
  </div>
</div>
</ng-template>
Plantilla cuando no esta logeado

Una vez esté logueado aparece el botón de logout

Error en el logueo

Si al momento de loguear aparece la pantalla momentáneamente y luego desaparece debes revisar la consola

code: "auth/operation-not-allowed"
message: "The identity provider configuration is disabled."

El error anterior pasa cuando no has habilitado el método de autenticación, para hacerlo debes ir a tu consola de firebase y habilitarlo

Debes habilitarlo para poderte logear

Añadir un dominio autorizado


Como Instalar Angularfire2 en Angular

martes, noviembre 5th, 2019

Que es AngularFire2

AngularFire2 es la librería que se usa en angular para acceder a bases de datos firebase, posee una serie de objetos para acceder a tus documentos de FireStore o RealTime Data Base.

Puedes encontrar más información sobre esta librería en el repositorio público de GitHub aquí

Como Se Instalar AngularFire2

Como cualquier otro paquete en angular se debe instalar a través de NPM, sino sabes que es NPM te invito a que visites el siguiente enlace

En pocas palabras NPM te permite instalar cualquier librería no solo de angular sino también de otros entornos de programación.

El comando que debes ejecutar para instalar es el siguiente

Versiones mas recientes

ng add @angular/fire
npm install firebase angularfire2 --save

También puedes instalar usando el comando latest para que se te instale la última versión del angularfire2, esto es así

npm install -S firebase@latest

El parámetro –save es para que se guarde en el proyecto actual, no esta demás decir que debes estar en el directorio de trabajo de tu proyecto de angular.

Al momento de escribir este post la versión actual es angularfire2 5.2.1, como lo estoy instalando en un proyecto que ya tiene mas de un año de haberse generado, me dio el siguiente error:

ERROR in node_modules/@angular/fire/firebase.app.module.d.ts(17,22): error TS2420: Class 'FirebaseApp' incorrectly implements interface 'App'.
  Type 'FirebaseApp' is missing the following properties from type 'App': installations, performance, remoteConfig, analytics

En mi caso sucedió que la versión de la librería de firebase no era la correcta para trabajar con angularfire esto me olbligó a instalar la version 5.10.1, por lo que tuve que correr el siguiente comando

npm install --save firebase@5.10.1

Asegurate de tener siempre la version compatible con tu angularfire2, o tendrás problemas, recuerda que una cosa es la librería de angularfire2 y otra la de firebase.

Si al momento de ejecutar tu app recibes un error como el siguiente:

ERROR in node_modules/@angular/fire/firebase.app.module.d.ts(17,22): error TS2420: Class 'FirebaseApp' incorrectly implements interface 'App'. Property 'performance' is missing in type 'FirebaseApp' but required in type 'App'.

Ejecuta el siguiente comando para que te actualize bien las dependencias y librerías necesarias

npm install firebase @angular/fire --save

Por lo menos en mi caso se resolvió el problema, si sigues teniendo algún inconveniente dejame un comentario.

Como usar AngularFire2

Generar la variable de acceso a la base de datos que te brinda Firebase, para ejemplo te puede quedar como la que se ve a continuación:

firebase: {
    apiKey: "qwijewknewhewhjwbjd23922SDSj2",
    authDomain: "hdhd.223.firebaseapp.com",
    databaseURL: "https://hdhd.223.firebaseio.com",
    projectId: "hdhd.223",
    storageBucket: "hdhd.223.appspot.com",
    messagingSenderId: "293923232",
    appId: "1:293923232:web:293923232a0c16c73d40d",
    measurementId: "G-SJDHSKDKW"
  }

Debe quedar mas o menos asi:

Agregar al app.module.ts lo siguiente

import { AngularFireModule } from '@angular/fire';
import { environment } from '../environments/environment';
import { AngularFireAnalyticsModule } from '@angular/fire/analytics';
import { AngularFirestoreModule } from '@angular/fire/firestore';

Te debe quedar así:

Declarar las importaciones de los módulos de angular en el proyecto

  AngularFireModule.initializeApp(environment.firebase),
  AngularFireAnalyticsModule,
  AngularFirestoreModule,


Funciones Cloud de FireBase

sábado, noviembre 2nd, 2019

Hace tiempo desarrollé dos aplicaciones en angular, usando como backend la base de datos firebase; como estaba aprendiendo la plataforma y familiarizandome con los nuevos conceptos, fue difícil entender algunos conceptos nuevos.

Uno de los hechos que mas me desconcertó fue el hecho que en la bases de datos NOSQL no se pueden hacer consultas sum() avg() max() min().

Para poder solventar esta situación, muchos blogs sugieren usar funciones cloud, estas trabajan del lado del servidor, obteniendo y manipulando la data, a continuación te comparto lo que encontré en mi búsqueda por resolver este problema.

Cloud Functions de Firebase

Primero que nada debemos instalar la herramientas de firebase Tools en nuestro proyecto local.

npm install -g firebase-tools

Luego hay que crear un directorio antes que pueda almacenar nuestro proyecto, como uso Linux, este procedimiento de crear un proyecto se crea muy fácilmente

cd ~/Documents/DESARROLLO/angular
mkdir fb
cd fb/

Una vez creado instaladas la firebase tools y creado un directorio de trabajo podemos iniciar sesion en firebase, para esto debemos escribir en la consola el siguiente comando

firebase login

con esto nos deplegará un login de google donde podemos seleccionar la cuenta en la cual tenemos almacenados nuestros proyectos de firebase

Seleccionamos la cuenta y podemos logearnos para crear un proyecto ó bien seleccionar un proyecto de los que tenemos en la consola

firebase init functions

Con el comando anterior ya podemos crear un directorio para trabajar con las funciones de firebase, nos quedará una estructura de archivo como la siguiente.

Fuente de este tutorial: https://carlosazaustre.es/que-son-las-firebase-cloud-functions/

Escribiendo una función en firebase

En el paso anterior vimos como hacer para poder configurar un proyecto de funciones firebase, ahora veremos como escribir la primera función firebase, para este tutorial usamos como fuente el video de codigofacilito que puedes visitar aquí

Me gustó mucho este tutorial por que esta escrito con TypeScript, y en angular se trabaja con TypeScript, por eso se me hizo más fácil seguirlo, muy buen trabajo de nuestros amigos de CodigoFacilito.com

Paso 1) iniciar el proyecto

Debemos iniciar el proyecto estando en el directorio que creamos anteriormente, y ejecutar el comando siguiente

firebase init 

Esto nos despliega una pantalla con el siguiente menú

Debes seleccionar Functions con la barra espaciadora y presionar enter, a continuación te pedirá si deseas crear un proyecto nuevo o como en mi caso seleccionar uno que ya existe

luego te preguntará el lenguaje que usaras para escribir las funciones

te pedirá que instales las dependencias entre otras cosas, yo le di que si a todo, haz lo mismo

Cuando termine de instalarse las dependencias tendrás listo el directorio para poder escribir tus funciones.

Abriremos el archivo index.ts que se encuentra en la carpeta src de nuestro proyecto

Y ahora si podemos escribir nuestra función perfectamente, para el ejemplo escribiremos una función que nos devuelva un hola mundo desde una dirección en internet, algo que debes entender de firebase Cloud Functions es que son el equivalente a los archivo php de nuestro servidor apache, escribe lo siguiente en el archivo

index.ts 
import * as funciones from 'firebase-functions';
exports.add=funciones.https.onRequest((req,res)=>{
    res.send('<p>'+'Hola Mundo'+'</p>');
});

Una vez hecha la función hay que deployarla en el servidor

firebase deploy --only functions

Atención: a partir de enero 2020 lo planes de facturación para Cloud Functions de Firebase cambian, es importante que atiendas este documento en el que te explico la nueva forma de cobrar de firebase

para ver el resultado debes ejecutar en el navegador la dirección de tu función en el servidor de firebase, por supuesto que esto varía según la cuenta del usuario y proyecto seleccionado

https://us-central1-TUPROYECTO.cloudfunctions.net/add

DEBES SUSTITUIR TUPROYECTO POR EL NOMBRE DE TU PROYECTO

Y verás el resultado de tu función en el navegador

Cloud Function para escribir en una base de datos

También es posible utilizar Cloud Function para escribir en una base de datos de Firebase, para esto necesitamos instalar la librería el SDK de firebase-admin

npm install firebase-admin --save

una vez instalado debemos importarla al proyecto en el archivo index.ts

import * as admin from 'firebase-admin';

a continuación hay que inicializar la app con el comando initializeApp

admin.initializeApp(funciones.config().firebase);

Luego ya podemos empezar agregando un valor a una colección de Cloud Firestore

admin.firestore().collection('nuevo').add({
        text:req.query.text
    }).then(r=>{
        res.send('completado');
    }).catch(err=>{
        res.send('hubo un error');
    })

Ahora debemos consumir a function enviando un parámetro para que pueda ser recibido por la function e introducido en una colección

https://us-central1-TUPROYECTO.cloudfunctions.net/add?text=nuevo

La función tomará el parámetro y lo introducirá en la colección

Triggers en Cloud Firestore

Todo lo anterior esta muy bien, pero todavía no definimos como definiremos las funciones de agregado: sum(), avg(), max(), min().

Lo primero es que si venimos del mundo SQL, es obligación cambiar nuestra manera de organizar los datos.

Por ejemplo en bases de datos NOSQL como FireStore, no puedes obtener el conteo de una colección, sin consumir gran cantidad de transacciones del servidor.

Puesto que el cobro por transacción, es la forma de facturar que aplica Firebase, es indispensable que tengamos en cuenta lo siguiente:

Si tuvieras una colección con los pagos que ha realizado un usuario, y quisieras saber el monto total de los pagos, siendo que este usuario ha realizado 1k transacciones este año.

Para saber ese dato tendrías que realizar 1k transacciones para leer la base de datos y sumar a uno por uno los pagos, como el cobro se hace por transacción y hay un límite al momento de escribir este artículo de 50k diarias en la versión gratis, con solo 50 usuarios que consulten su historial de pagos, tu plan gratuito pasaría al siguiente nivel y se te cobraría.

Es por eso que cuando usas Firebase, lo correcto es usar una cloud Function que se encargue de escribir los valores de agregado en un documento aparte.

A continuación te muestro como resolví este problema, usando el siguiente video de codigofacilito.com, en el cual se explica perfectamente este punto

Primero que nada creamos una colección en la base de datos para contener el numero de registros, debes ir a tu consola web y crear lo siguiente

Luego debemos ir al archivo index.ts y agregar una nueva función lo cual hacemos así

exports.contador=funciones.firestore.document('nuevo/{itemid}').onCreate((ev)=>{
    
});

Importante destacar que el {itemid} es un wildcard que sirve para ser sustituido con el id del documento que se está agregando

A continuación debemos crear una referencia que apunte al contador


exports.contador=funciones.firestore.document('nuevo/{itemid}').onCreate((ev)=>{

    const doc =admin.firestore().doc('counter/items');
    
});

hecho esto ya podemos usar el método get() para obtener el documento counter obtener el valor, sumarle uno y luego actualizarlo en la bd

 return doc.get().then(
        (result)=>{
            const info = { value: result.data()!.value +  1 };
            return doc.update(info);
    })  

Esta porción de código obtiene el valor le suma uno y lo escribe en el contador, importante ver el símbolo de admiración que hay en result.data()! esto es así para decirle que ignore la posibilidad que el valor devuelva un null, con esto asumimos que el documento counter siempre existirá.

El código completo del archivo index.ts queda así

import * as funciones from 'firebase-functions';
import * as admin from 'firebase-admin';

admin.initializeApp(funciones.config().firebase);
//las functions 
exports.add=funciones.https.onRequest((req,res)=>{
    //res.send('<p>'+'Hola Mundo'+'</p>');
    admin.firestore().collection('nuevo').add({
        text:req.query.text
    }).then(r=>{
        res.send('completado');
    }).catch(err=>{
        res.send('hubo un error');
    })
});

exports.contador=funciones.firestore.document('nuevo/{itemid}').onCreate((ev)=>{
    const doc =admin.firestore().doc('counter/items');
 
      return doc.get().then(
        (result)=>{
            const info = { value: result.data()!.value +  1 };
            return doc.update(info);
    })  
})

y el resultado final es el siguiente en la bd



Redes sociales