All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.firebase.database.DataSnapshot Maven / Gradle / Ivy

/*
 * Copyright 2017 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.firebase.database;

import com.google.firebase.database.annotations.Nullable;
import com.google.firebase.database.core.Path;
import com.google.firebase.database.snapshot.IndexedNode;
import com.google.firebase.database.snapshot.NamedNode;
import com.google.firebase.database.snapshot.Node;
import com.google.firebase.database.utilities.Validation;
import com.google.firebase.database.utilities.encoding.CustomClassMapper;

import java.util.Iterator;

/**
 * A DataSnapshot instance contains data from a Firebase Database location. Any time you read
 * Database data, you receive the data as a DataSnapshot. 
*
* DataSnapshots are passed to the methods in listeners that you attach with {@link * DatabaseReference#addValueEventListener(ValueEventListener)}, {@link * DatabaseReference#addChildEventListener(ChildEventListener)}, or {@link * DatabaseReference#addListenerForSingleValueEvent(ValueEventListener)}.
*
* They are efficiently-generated immutable copies of the data at a Firebase Database location. They * can't be modified and will never change. To modify data at a location, use a {@link * DatabaseReference DatabaseReference} reference (e.g. with {@link * DatabaseReference#setValueAsync(Object)}). */ public class DataSnapshot { private final IndexedNode node; private final DatabaseReference query; /** * @param ref A DatabaseReference * @param node The indexed node */ DataSnapshot(DatabaseReference ref, IndexedNode node) { this.node = node; this.query = ref; } /** * Get a DataSnapshot for the location at the specified relative path. The relative path can * either be a simple child key (e.g. 'fred') or a deeper slash-separated path (e.g. * 'fred/name/first'). If the child location has no data, an empty DataSnapshot is returned. * * @param path A relative path to the location of child data * @return The DataSnapshot for the child location */ public DataSnapshot child(String path) { DatabaseReference childRef = query.child(path); Node childNode = this.node.getNode().getChild(new Path(path)); return new DataSnapshot(childRef, IndexedNode.from(childNode)); } /** * Can be used to determine if this DataSnapshot has data at a particular location * * @param path A relative path to the location of child data * @return Whether or not the specified child location has data */ public boolean hasChild(String path) { if (query.getParent() == null) { Validation.validateRootPathString(path); } else { Validation.validatePathString(path); } return !node.getNode().getChild(new Path(path)).isEmpty(); } /** * Indicates whether this snapshot has any children * * @return True if the snapshot has any children, otherwise false */ public boolean hasChildren() { return node.getNode().getChildCount() > 0; } /** * Returns true if the snapshot contains a non-null value. * * @return True if the snapshot contains a non-null value, otherwise false */ public boolean exists() { return !node.getNode().isEmpty(); } /** * getValue() returns the data contained in this snapshot as native types. The possible types * returned are: * *
    *
  • Boolean *
  • String *
  • Long *
  • Double *
  • Map<String, Object> *
  • List<Object> *
* *

This list is recursive; the possible types for Object in the above list * is given by the same list. These types correspond to the types available in JSON. * * @return The data contained in this snapshot as native types or null if there is no data at this * location. */ @Nullable public Object getValue() { return node.getNode().getValue(); } /** * getValue() returns the data contained in this snapshot as native types. The possible types * returned are: * *

    *
  • Boolean *
  • String *
  • Long *
  • Double *
  • Map<String, Object> *
  • List<Object> *
* *

This list is recursive; the possible types for Object in the above list is * given by the same list. These types correspond to the types available in JSON. * *

If useExportFormat is set to true, priority information will be included in the output. * Priority information shows up as a .priority key in a map. For data that would not otherwise be * a map, the map will also include a .value key with the data. * * @param useExportFormat Whether or not to include priority information * @return The data, along with its priority, in native types or null if there is no data at this * location. */ @Nullable public Object getValue(boolean useExportFormat) { return node.getNode().getValue(useExportFormat); } /** * This method is used to marshall the data contained in this snapshot into a class of your * choosing. The class must fit 2 simple constraints: * *

    *
  1. The class must have a default constructor that takes no arguments *
  2. The class must define public getters for the properties to be assigned. Properties * without a public getter will be set to their default value when an instance is * deserialized *
* *

An example class might look like: * *


   *     class Message {
   *         private String author;
   *         private String text;
   *
   *         private Message() {}
   *
   *         public Message(String author, String text) {
   *             this.author = author;
   *             this.text = text;
   *         }
   *
   *         public String getAuthor() {
   *             return author;
   *         }
   *
   *         public String getText() {
   *             return text;
   *         }
   *     }
   *
   *
   *     // Later
   *     Message m = snapshot.getValue(Message.class);
   * 
* * @param valueType The class into which this snapshot should be marshalled * @param The type to return. Implicitly defined from the class passed in * @return An instance of the class passed in, populated with the data from this snapshot, or null * if there is no data at this location. */ @Nullable public T getValue(Class valueType) { Object value = node.getNode().getValue(); return CustomClassMapper.convertToCustomClass(value, valueType); } /** * Due to the way that Java implements generics, it takes an extra step to get back a * properly-typed Collection. So, in the case where you want a List of Message * instances, you will need to do something like the following: * *

   *     GenericTypeIndicator<List<Message>> t = new GenericTypeIndicator<List<
   *     Message>>()
   * {};
   *     List<Message> messages = snapshot.getValue(t);
   * 
* *

It is important to use a subclass of {@link GenericTypeIndicator}. See {@link * GenericTypeIndicator} for more details * * @param t A subclass of {@link GenericTypeIndicator} indicating the type of generic collection * to be returned. * @param The type to return. Implicitly defined from the {@link GenericTypeIndicator} passed * in * @return A properly typed collection, populated with the data from this snapshot, or null if * there is no data at this location. */ @Nullable public T getValue(GenericTypeIndicator t) { Object value = node.getNode().getValue(); return CustomClassMapper.convertToCustomClass(value, t); } /** * @return The number of immediate children in the this snapshot */ public long getChildrenCount() { return node.getNode().getChildCount(); } /** * Used to obtain a reference to the source location for this snapshot. * * @return A DatabaseReference corresponding to the location that this snapshot came from */ public DatabaseReference getRef() { return query; } /** * @return the key name for the source location of this snapshot */ public String getKey() { return query.getKey(); } /** * Gives access to all of the immediate children of this snapshot. Can be used in native for * loops: *
for (DataSnapshot child : parent.getChildren()) { *
    ... *
} *
* * @return The immediate children of this snapshot */ public Iterable getChildren() { final Iterator iter = node.iterator(); return new Iterable() { @Override public Iterator iterator() { return new Iterator() { @Override public boolean hasNext() { return iter.hasNext(); } @Override public DataSnapshot next() { NamedNode namedNode = iter.next(); return new DataSnapshot( query.child(namedNode.getName().asString()), IndexedNode.from(namedNode.getNode())); } @Override public void remove() { throw new UnsupportedOperationException("remove called on immutable collection"); } }; } }; } /** * Returns the priority of the data contained in this snapshot as a native type. Possible return * types: * *

    *
  • Double *
  • String *
* *

Note that null is also allowed. * * @return the priority of the data contained in this snapshot as a native type */ public Object getPriority() { Object priority = node.getNode().getPriority().getValue(); if (priority instanceof Long) { return Double.valueOf((Long) priority); } else { return priority; } } @Override public String toString() { return "DataSnapshot { key = " + this.query.getKey() + ", value = " + this.node.getNode().getValue(true) + " }"; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy