Ir a la consola

Guarda datos

Antes de comenzar

Sigue estos pasos para usar Realtime Database:

  • Registra tu proyecto de Unity y configúralo para usar Firebase.

    • Si tu proyecto de Unity ya usa Firebase, significa que ya está registrado y configurado para Firebase.

    • Si aún no tienes un proyecto de Unity, puedes descargar una app de muestra.

  • Agrega el SDK de Firebase Unity (en específico, FirebaseDatabase.unitypackage) al proyecto de Unity.

Ten en cuenta que agregar Firebase a tu proyecto de Unity implica realizar tareas en Firebase console y en tu proyecto abierto de Unity (por ejemplo, descargar archivos de configuración de Firebase desde la consola y moverlos a tu proyecto de Unity).

Guarda 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