Guarda datos

Antes de comenzar

Para usar Firebase Realtime Database, debes crear un proyecto de Firebase y agregar los paquetes del SDK de Firebase Unity al proyecto de Unity.

Configuración:

Requisitos previos

Android

  • Unity 5.0 o una versión más reciente
  • NDK de Android 10d o una versión más reciente

iOS

  • Unity 5.0 o una versión más reciente
  • Xcode 8.0 o una versión más reciente

Si todavía no tienes un proyecto de Unity, puedes descargar uno de los ejemplos de inicio rápido para probar una función de Firebase específica. Si usas un ejemplo de inicio rápido, recuerda consultar el identificador de paquete en la configuración del proyecto, ya que lo necesitarás en el próximo paso.

Configura la app en Firebase console

Para agregar Firebase a la app, debes tener un proyecto y un archivo de configuración de Firebase.

Para crear un proyecto de Firebase:

  1. Dirígete a Firebase console.

  2. Haz clic en Agregar proyecto, luego selecciona o ingresa un Nombre del proyecto.

    • Si hay un proyecto de Google existente asociado con tu app, selecciónalo desde el menú desplegable Nombre del proyecto.
    • Si no hay un proyecto de Google existente, ingresa un nuevo Nombre del proyecto.
  3. (Opcional) Edita el ID del proyecto.

    Firebase asignará de manera automática un ID único a tu proyecto de Firebase. Este identificador se muestra en los servicios de Firebase visibles de forma pública, por ejemplo:

    • URL predeterminada para la base de datos: your-project-id.firebaseio.com
    • Subdominio de hosting predeterminado: your-project-id.firebaseapp.com
  4. Sigue los pasos de configuración restantes y, luego, haz clic en Crear proyecto (o Agregar Firebase si usas un proyecto de Google existente).

Firebase aprovisiona los recursos para tu proyecto de forma automática. Este proceso suele tardar algunos minutos. Cuando finalice, verás la página descripción general del proyecto en Firebase console.

Android

  1. Haz clic en Agrega Firebase a tu app para Android y sigue los pasos de la configuración. Si importas un proyecto de Google existente, es posible que esto ocurra de forma automática y solo tengas que descargar el archivo de configuración.
  2. Ingresa el nombre del paquete de la app cuando se te solicite. Es importante que ingreses el nombre de paquete que usa la app. Esta configuración solo puede hacerse cuando agregas una app al proyecto de Firebase.
  3. Durante el proceso, descargarás un archivo google-services.json. Puedes volver a descargarlo en cualquier momento.
  4. Después de agregar el código de inicialización, ejecuta la app para verificar con Firebase console que instalaste Firebase correctamente.

iOS

  1. Haz clic en Agrega Firebase a la app para iOS y sigue los pasos de configuración. Si importas un proyecto de Google existente, es posible que esto ocurra de forma automática y solo tengas que descargar el archivo de configuración.
  2. Ingresa el ID del paquete de la app cuando se te solicite. Es importante que ingreses el ID del paquete que usa la app. Esta configuración solo puede hacerse cuando agregas una app al proyecto de Firebase.
  3. Durante el proceso, descargarás un archivo GoogleService-Info.plist. Puedes volver a descargarlo en cualquier momento.
  4. Después de agregar el código de inicialización, ejecuta la app para verificar con Firebase console que instalaste Firebase correctamente.
  5. Arrastra el archivo GoogleService-Info.plist que se descargó de Firebase console a cualquier carpeta del proyecto de Unity.

Agrega el SDK de Firebase Unity a la app

  1. Descarga el SDK de Firebase Unity.
  2. Selecciona el elemento de menú Activos > Importar paquete > Paquete personalizado.
  3. Importa FirebaseDatabase.unitypackage desde el directorio que coincide con la versión de Unity que usas:
    • Unity 5.x y las versiones anteriores usan .NET Framework 3.x, de modo que debes importar el paquete dotnet3/FirebaseDatabase.unitypackage .
    • Unity 2017.x y las versiones posteriores usan .NET Framework 4.x. Si tu proyecto está configurado para usar .NET 4.x, importa el paquete dotnet4/FirebaseDatabase.unitypackage .
  4. Cuando aparezca la ventana Importar paquete de Unity, haz clic en el botón Importar.

Inicializa el SDK

El SDK de Firebase Unity en Android requiere los Servicios de Google Play actualizados. Se debe agregar el siguiente código al inicio de la aplicación para buscar y, de forma opcional, actualizar los Servicios de Google Play a la versión que requiera el SDK de Firebase Unity a fin de que sea posible llamar a otros métodos en el SDK.

Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task => {
  var dependencyStatus = task.Result;
  if (dependencyStatus == Firebase.DependencyStatus.Available) {
    // Create and hold a reference to your FirebaseApp, i.e.
    //   app = Firebase.FirebaseApp.DefaultInstance;
    // where app is a Firebase.FirebaseApp property of your application class.

    // Set a flag here indicating that Firebase is ready to use by your
    // application.
  } else {
    UnityEngine.Debug.LogError(System.String.Format(
      "Could not resolve all Firebase dependencies: {0}", dependencyStatus));
    // Firebase Unity SDK is not safe to use here.
  }
});

Compila la app

Android

  1. Selecciona la opción de menú Archivo > Configuración de compilación.
  2. Selecciona Android en la lista Plataforma.
  3. Haz clic en Cambiar plataforma para establecer Android como plataforma seleccionada.
  4. Espera a que se detenga el ícono giratorio (de compilación en proceso) que se encuentra en la esquina inferior derecha de la barra de estado de Unity.
  5. Haz clic en Compilar y ejecutar.

iOS

  1. Selecciona la opción de menú Archivo > Configuración de compilación.
  2. Selecciona iOS en la lista Plataforma.
  3. Haz clic en Cambiar plataforma para establecer iOS como plataforma seleccionada.
  4. Espera a que se detenga el ícono giratorio (de compilación en proceso) que se encuentra en la esquina inferior derecha de la barra de estado de Unity.
  5. Haz clic en Compilar y ejecutar.

Cómo guardar datos

Existen cinco métodos para escribir datos en Firebase Realtime Database:

Método Usos comunes
SetValueAsync() Escribir o reemplazar datos en una ruta de acceso definida, como users/<user-id>/<username>.
SetRawJsonValueAsync() Escribir o reemplazar datos con Json sin procesar, como users/<user-id>/<username>.
Push() Agregar a una lista de datos. Cada vez que llamas a Push(), Firebase genera una clave única que también se puede usar como identificador único, por ejemplo user-scores/<user-id>/<unique-score-id>.
UpdateChildrenAsync() Actualizar algunas de las claves de una ruta de acceso definida sin reemplazar todos los datos.
RunTransaction() Actualizar datos complejos que podrían dañarse con actualizaciones simultáneas.

Obtén una DatabaseReference

Para escribir en la base de datos, necesitas una instancia de DatabaseReference:

using Firebase;
using Firebase.Database;
using Firebase.Unity.Editor;

public class MyScript: MonoBehaviour {
  void Start() {
    // Set up the Editor before calling into the realtime database.
    FirebaseApp.DefaultInstance.SetEditorDatabaseUrl("https://YOUR-FIREBASE-APP.firebaseio.com/");

    // Get the root reference location of the database.
    DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference;
  }
}

Escribe, actualiza o borra datos de una referencia

Operaciones básicas de escritura

Para ejecutar operaciones de escritura básicas, puedes usar SetValueAsync() a fin de guardar datos en una referencia que especifiques y reemplazar los datos existentes en esa ruta de acceso. Puedes usar este método para pasar tipos que corresponden a los JSON disponibles de la siguiente manera:

  • string
  • long
  • double
  • bool
  • Dictionary<string, Object>
  • List<Object>

Si usas un objeto tipo C#, puedes usar el elemento JsonUtility.ToJson() integrado para convertir el objeto en Json sin procesar y llamar a SetRawJsonValueAsync(). Por ejemplo, puedes tener una clase User similar a la siguiente:

public class User {
    public string username;
    public string email;

    public User() {
    }

    public User(string username, string email) {
        this.username = username;
        this.email = email;
    }
}

Puedes agregar un usuario con SetRawJsonValueAsync(), como se muestra a continuación:

private void writeNewUser(string userId, string name, string email) {
    User user = new User(name, email);
    string json = JsonUtility.ToJson(user);

    mDatabaseRef.Child("users").Child(userId).SetRawJsonValueAsync(json);
}

Cuando usas SetValueAsync() o SetRawJsonValueAsync() de esta forma, se reemplazan los datos en las ubicaciones especificadas, incluidos los nodos secundarios. Sin embargo, puedes actualizar un elemento secundario sin volver a escribir el objeto completo. Si quieres permitir que los usuarios actualicen sus perfiles, puedes actualizar el nombre de usuario de la siguiente forma:

mDatabaseRef.Child("users").Child(userId).Child("username").SetValueAsync(name);

Agrega datos a una lista de datos

Usa el método Push() para agregar datos a una lista en aplicaciones multiusuario. Cada vez que se agrega un nuevo elemento secundario a la referencia de Firebase especificada, el método Push() genera una clave única. Cuando se usan estas claves generadas de forma automática para cada elemento nuevo de la lista, varios clientes pueden agregar elementos secundarios a la misma ubicación, al mismo tiempo y sin conflictos de escritura. La clave única que genera Push() se basa en una marca de tiempo. Por lo tanto, los elementos de las listas se ordenan cronológicamente de forma automática.

Puedes usar la referencia a los nuevos datos que muestra el método Push() para obtener el valor de la clave generada automáticamente del elemento secundario o configurar los datos de dicho elemento. Si llamas a Key en una referencia Push(), se muestra la clave generada de forma automática.

Actualiza campos específicos

Para escribir de manera simultánea en elementos secundarios específicos de un nodo sin reemplazar otros nodos secundarios, usa el método UpdateChildrenAsync().

Cuando llamas a UpdateChildrenAsync(), puedes especificar una ruta de acceso de la clave para actualizar valores secundarios de nivel inferior. Si se almacenan datos en varias ubicaciones para obtener un mejor escalamiento, puedes actualizar todas las instancias de esos datos mediante fan-out de datos. Por ejemplo, un juego puede tener una clase LeaderboardEntry como la siguiente:

public class LeaderboardEntry {
    public string uid;
    public int score = 0;

    public LeaderboardEntry() {
    }

    public LeaderboardEntry(string uid, int score) {
        this.uid = uid;
        this.score = score;
    }

    public Dictionary&ltstring, Object&gt ToDictionary() {
        Dictionary&ltstring, Object&gt result = new Dictionary&ltstring, Object&gt();
        result["uid"] = uid;
        result["score"] = score;

        return result;
    }
}

Para crear una LeaderboardEntry y actualizarla de forma simultánea en el feed de puntuación reciente y en la lista de puntuaciones propia del usuario, el juego usa el siguiente código:

private void WriteNewScore(string userId, int score) {
    // Create new entry at /user-scores/$userid/$scoreid and at
    // /leaderboard/$scoreid simultaneously
    string key = mDatabase.Child("scores").Push().Key;
    LeaderBoardEntry entry = new LeaderBoardEntry(userId, score);
    Dictionary&ltstring, Object&gt entryValues = entry.ToDictionary();

    Dictionary&ltstring, Object&gt childUpdates = new Dictionary&ltstring, Object&gt();
    childUpdates["/scores/" + key] = entryValues;
    childUpdates["/user-scores/" + userId + "/" + key] = entryValues;

    mDatabase.UpdateChildrenAsync(childUpdates);
}

Este ejemplo utiliza Push() para crear una entrada en el nodo que contiene las entradas para todos los usuarios en /scores/$key y recupera la clave con Key de forma simultánea. Luego, la clave se puede usar para crear una segunda entrada en las puntuaciones del usuario, en /user-scores/$userid/$key.

Con estas rutas de acceso, puedes ejecutar actualizaciones simultáneas en varias ubicaciones del árbol JSON con una única llamada a UpdateChildrenAsync(), de manera similar a este ejemplo en el que se crea la entrada nueva en ambas ubicaciones. Las actualizaciones simultáneas que se ejecutan de esta forma son atómicas, es decir, todas se aplican correctamente o todas fallan.

Borra datos

La forma más sencilla de borrar datos es llamar a RemoveValue() en una referencia a la ubicación de los datos.

Otra forma de borrar datos es especificar null como valor para otra operación de escritura, como SetValueAsync() o UpdateChildrenAsync(). Puedes usar esta técnica con UpdateChildrenAsync() para borrar varios elementos secundarios en una sola llamada de API.

Conoce cuándo se envían los datos

Para saber cuándo se envían los datos al servidor de Firebase Realtime Database, puedes agregar una continuación. Tanto SetValueAsync() como UpdateChildrenAsync() muestran la tarea Task, que permite saber cuándo se completa la operación. Si por algún motivo, la llamada no funciona correctamente, la propiedad IsFaulted de la tarea tendrá el valor True, y la propiedad Exception indicará el motivo del error.

Guarda datos como transacciones

Cuando trabajas con datos que se podrían dañar si se hacen cambios simultáneos (por ejemplo, contadores incrementales), puedes usar una operación de transacción. Le debes asignar Func. Esta Func de actualización toma el estado actual de los datos como argumento y da como resultado el nuevo estado que deseas escribir. Si otro cliente escribe en la ubicación antes de que se escriba de manera correcta el valor nuevo, se vuelve a llamar la función de actualización con el nuevo valor actual y se intenta nuevamente la operación de escritura.

Por ejemplo, en un juego, podrías permitir que los usuarios actualicen una tabla de clasificación con las cinco puntuaciones más altas:

private void AddScoreToLeaders(string email,
                               long score,
                               DatabaseReference leaderBoardRef) {

    leaderBoardRef.RunTransaction(mutableData =&gt {
      List&ltobject&gt leaders = mutableData.Value as List&ltobject>

      if (leaders == null) {
        leaders = new List&ltobject&gt();
      } else if (mutableData.ChildrenCount &gt= MaxScores) {
        long minScore = long.MaxValue;
        object minVal = null;
        foreach (var child in leaders) {
          if (!(child is Dictionary&ltstring, object&gt)) continue;
          long childScore = (long)
                      ((Dictionary&ltstring, object&gt)child)["score"];
          if (childScore &lt minScore) {
            minScore = childScore;
            minVal = child;
          }
        }
        if (minScore &gt score) {
          // The new score is lower than the existing 5 scores, abort.
          return TransactionResult.Abort();
        }

        // Remove the lowest score.
        leaders.Remove(minVal);
      }

      // Add the new high score.
      Dictionary&ltstring, object&gt newScoreMap =
                       new Dictionary&ltstring, object&gt();
      newScoreMap["score"] = score;
      newScoreMap["email"] = email;
      leaders.Add(newScoreMap);
      mutableData.Value = leaders;
      return TransactionResult.Success(mutableData);
    });
}

Si usas una transacción, impides que la tabla de clasificación sea incorrecta en caso de que varios usuarios registren puntuaciones al mismo tiempo o el cliente tenga datos inactivos. Si se rechaza la transacción, el servidor le muestra el valor actual al cliente, que vuelve a ejecutar la transacción con el valor actualizado. Esto se repite hasta que se acepte la transacción o hasta que se registren demasiados intentos.

Escribe datos sin conexión

Si un cliente pierde la conexión de red, la app continúa funcionando de manera correcta.

Todos los clientes conectados a una base de datos de Firebase mantienen su propia versión interna de los datos activos. Cuando se escriben datos, se hace primero en esta versión local. Después, el cliente de Firebase sincroniza esos datos con los servidores de bases de datos remotas y con otros clientes según el “mejor esfuerzo”.

Como resultado, todas las operaciones de escritura en la base de datos activan eventos locales al instante, antes de que se escriban datos en el servidor. Esto significa que la app conserva la capacidad de respuesta, sin importar la latencia o el estado de conexión de la red.

Cuando se restablece la conexión, la app recibe el conjunto de eventos adecuado, de manera que el cliente se sincroniza con el estado actual del servidor sin tener que escribir código personalizado.

Pasos siguientes

Enviar comentarios sobre…

¿Necesitas ayuda? Visita nuestra página de asistencia.