Full Code of rlamasb/Firebase.Xamarin for AI

master 1fbd4149a048 cached
47 files
118.9 KB
27.7k tokens
202 symbols
1 requests
Download .txt
Repository: rlamasb/Firebase.Xamarin
Branch: master
Commit: 1fbd4149a048
Files: 47
Total size: 118.9 KB

Directory structure:
gitextract_p1_b5ys5/

├── .gitignore
├── Auth/
│   ├── FirebaseAuth.cs
│   ├── FirebaseAuthException.cs
│   ├── FirebaseAuthLink.cs
│   ├── FirebaseAuthProvider.cs
│   ├── FirebaseAuthType.cs
│   ├── FirebaseConfig.cs
│   ├── IFirebaseAuthProvider.cs
│   └── User.cs
├── Database/
│   ├── FirebaseClient.cs
│   ├── FirebaseKeyGenerator.cs
│   ├── FirebaseObject.cs
│   ├── GlobalSuppressions.cs
│   ├── Http/
│   │   ├── HttpClientExtensions.cs
│   │   └── PostResult.cs
│   ├── ObservableExtensions.cs
│   ├── Offline/
│   │   ├── ExceptionEventArgs.cs
│   │   ├── OfflineCacheAdapter.cs
│   │   ├── OfflineEntry.cs
│   │   ├── RealtimeDatabase.cs
│   │   └── SyncOptions.cs
│   ├── Properties/
│   │   └── AssemblyInfo.cs
│   ├── Query/
│   │   ├── AuthQuery.cs
│   │   ├── ChildQuery.cs
│   │   ├── FilterQuery.cs
│   │   ├── FirebaseQuery.cs
│   │   ├── IFirebaseQuery.cs
│   │   ├── OrderQuery.cs
│   │   ├── ParameterQuery.cs
│   │   ├── QueryExtensions.cs
│   │   └── QueryFactoryExtensions.cs
│   └── Streaming/
│       ├── FirebaseCache.cs
│       ├── FirebaseEvent.cs
│       ├── FirebaseEventType.cs
│       ├── FirebaseServerEventType.cs
│       └── FirebaseSubscription.cs
├── Firebase.Xamarin.csproj
├── Firebase.Xamarin.sln
├── LICENSE
├── Notification/
│   └── PushNotification.cs
├── Properties/
│   └── AssemblyInfo.cs
├── README.md
├── Token/
│   ├── StreamToken.cs
│   ├── TokenGenerator.cs
│   └── TokenOptions.cs
├── TokenGenerator.config
└── packages.config

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
#Autosave files
*~

#build
[Oo]bj/
[Bb]in/
packages/
TestResults/

# globs
Makefile.in
*.DS_Store
*.sln.cache
*.suo
*.cache
*.pidb
*.userprefs
*.usertasks
config.log
config.make
config.status
aclocal.m4
install-sh
autom4te.cache/
*.user
*.tar.gz
tarballs/
test-results/
Thumbs.db

#Mac bundle stuff
*.dmg
*.app

#resharper
*_Resharper.*
*.Resharper

#dotCover
*.dotCover


================================================
FILE: Auth/FirebaseAuth.cs
================================================
namespace Firebase.Xamarin.Auth
{
    using Newtonsoft.Json;

    /// <summary>
    /// The firebase auth.
    /// </summary>
    public class FirebaseAuth
    {
        /// <summary>
        /// Gets or sets the firebase token which can be used for authenticated queries. 
        /// </summary>
        [JsonProperty("idToken")]
        public string FirebaseToken
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the refresh token of the underlying service which can be used to get a new access token. 
        /// </summary>
        [JsonProperty("refreshToken")]
        public string RefreshToken
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the numbers of seconds until the token expires.
        /// </summary>
        [JsonProperty("expiresIn")]
        public int ExpiresIn
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the user.
        /// </summary>
        public User User
        {
            get;
            set;
        }
    }
}


================================================
FILE: Auth/FirebaseAuthException.cs
================================================
using System;
using System.Runtime.Serialization;

namespace Firebase.Xamarin.Auth
{
	/*
	 * Sign In Exceptions 
	 */
	public class FirebaseIncorrectPasswordException : Exception
	{
		/// <summary>
		/// Default constructor
		/// </summary>
		public FirebaseIncorrectPasswordException() : base()
		{
		}

		/// <summary>
		/// Argument constructor
		/// </summary>
		/// <param name="message">This is the description of the exception</param>
		public FirebaseIncorrectPasswordException(String message) : base(message)
		{
		}

		/// <summary>
		/// Argument constructor with inner exception
		/// </summary>
		/// <param name="message">This is the description of the exception</param>
		/// <param name="innerException">Inner exception</param>
		public FirebaseIncorrectPasswordException(String message, Exception innerException) : base(message, innerException)
		{
		}
	}

	public class FirebaseInvalidEmailException : Exception
	{
		/// <summary>
		/// Default constructor
		/// </summary>

		public FirebaseInvalidEmailException() : base()
		{
		}

		/// <summary>
		/// Argument constructor
		/// </summary>
		/// <param name="message">This is the description of the exception</param>

		public FirebaseInvalidEmailException(String message) : base(message)
		{
		}

		/// <summary>
		/// Argument constructor with inner exception
		/// </summary>
		/// <param name="message">This is the description of the exception</param>
		/// <param name="innerException">Inner exception</param>

		public FirebaseInvalidEmailException(String message, Exception innerException) : base(message, innerException)
		{
		}
	}

	/*
	 * Create User Exceptions
	 */
	public class FirebaseUsedEmailException : Exception
	{
		/// <summary>
		/// Default constructor
		/// </summary>

		public FirebaseUsedEmailException() : base()
		{
		}

		/// <summary>
		/// Argument constructor
		/// </summary>
		/// <param name="message">This is the description of the exception</param>

		public FirebaseUsedEmailException(String message) : base(message)
		{
		}

		/// <summary>
		/// Argument constructor with inner exception
		/// </summary>
		/// <param name="message">This is the description of the exception</param>
		/// <param name="innerException">Inner exception</param>

		public FirebaseUsedEmailException(String message, Exception innerException) : base(message, innerException)
		{
		}
	}

	public class FirebaseWeakPasswordException : Exception
	{
		/// <summary>
		/// Default constructor
		/// </summary>

		public FirebaseWeakPasswordException() : base()
		{
		}

		/// <summary>
		/// Argument constructor
		/// </summary>
		/// <param name="message">This is the description of the exception</param>

		public FirebaseWeakPasswordException(String message) : base(message)
		{
		}

		/// <summary>
		/// Argument constructor with inner exception
		/// </summary>
		/// <param name="message">This is the description of the exception</param>
		/// <param name="innerException">Inner exception</param>

		public FirebaseWeakPasswordException(String message, Exception innerException) : base(message, innerException)
		{
		}
	}
}



================================================
FILE: Auth/FirebaseAuthLink.cs
================================================
namespace Firebase.Xamarin.Auth
{
    using System.Threading.Tasks;

    /// <summary>
    /// The firebase auth which can be linked to another credentials.
    /// </summary>
    public class FirebaseAuthLink : FirebaseAuth
    {
        internal FirebaseAuthLink()
        {
        }

        internal FirebaseAuthProvider AuthProvider 
        {
            get;
            set;
        }

        /// <summary>
        /// Links the user with an email and password.  
        /// </summary>
        /// <param name="email"> The email. </param>
        /// <param name="password"> The password. </param>
        /// <returns> The <see cref="FirebaseAuthLink"/>. </returns>
        public Task<FirebaseAuthLink> LinkToAsync(string email, string password)
        {
            return this.AuthProvider.LinkAccountsAsync(this, email, password);
        }

        /// <summary>
        /// Links the this user with and account from a third party provider.
        /// </summary> 
        /// <param name="authType"> The auth type.  </param>
        /// <param name="oauthAccessToken"> The access token retrieved from login provider of your choice. </param>
        /// <returns> The <see cref="FirebaseAuthLink"/>.  </returns>
        public Task<FirebaseAuthLink> LinkToAsync(FirebaseAuthType authType, string oauthAccessToken)
        {
            return this.AuthProvider.LinkAccountsAsync(this, authType, oauthAccessToken);
        }
    }
}


================================================
FILE: Auth/FirebaseAuthProvider.cs
================================================
namespace Firebase.Xamarin.Auth
{
	using System;
	using System.Linq;
	using System.Net.Http;
	using System.Text;
	using System.Threading.Tasks;

	using Newtonsoft.Json;
	using Newtonsoft.Json.Linq;

	/// <summary>
	/// The auth token provider.
	/// </summary>
	public class FirebaseAuthProvider : IDisposable, IFirebaseAuthProvider
	{
		private const string GoogleIdentityUrl = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyAssertion?key={0}";
		private const string GoogleSignUpUrl = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key={0}";
		private const string GooglePasswordUrl = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key={0}";
		private const string GooglePasswordResetUrl = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/getOobConfirmationCode?key={0}";
		private const string GoogleSetAccountUrl = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/setAccountInfo?key={0}";

		private readonly FirebaseConfig authConfig;
		private readonly HttpClient client;

		/// <summary>
		/// Initializes a new instance of the <see cref="FirebaseAuthProvider"/> class.
		/// </summary>
		/// <param name="authConfig"> The auth config. </param>
		public FirebaseAuthProvider(FirebaseConfig authConfig)
		{
			this.authConfig = authConfig;
			this.client = new HttpClient();
		}

		/// <summary>
		/// Using the provided access token from third party auth provider (google, facebook...), get the firebase auth with token and basic user credentials.
		/// </summary>
		/// <param name="authType"> The auth type. </param>
		/// <param name="oauthAccessToken"> The access token retrieved from login provider of your choice. </param>
		/// <returns> The <see cref="FirebaseAuth"/>. </returns>
		public async Task<FirebaseAuthLink> SignInWithOAuthAsync(FirebaseAuthType authType, string oauthAccessToken)
		{
			var providerId = this.GetProviderId(authType);
			var content = $"{{\"postBody\":\"access_token={oauthAccessToken}&providerId={providerId}\",\"requestUri\":\"http://localhost\",\"returnSecureToken\":true}}";

			return await this.SignInWithPostContentAsync(GoogleIdentityUrl, content).ConfigureAwait(false);
		}

		/// <summary>
		/// Sign in user anonymously. He would still have a user id and access token generated, but name and other personal user properties will be null.
		/// </summary>
		/// <returns> The <see cref="FirebaseAuth"/>. </returns>
		public async Task<FirebaseAuthLink> SignInAnonymouslyAsync()
		{
			var content = $"{{\"returnSecureToken\":true}}";

			return await this.SignInWithPostContentAsync(GoogleSignUpUrl, content).ConfigureAwait(false);
		}

		/// <summary>
		/// Using the provided email and password, get the firebase auth with token and basic user credentials.
		/// </summary>
		/// <param name="email"> The email. </param>
		/// <param name="password"> The password. </param>
		/// <returns> The <see cref="FirebaseAuth"/>. </returns>
		public async Task<FirebaseAuthLink> SignInWithEmailAndPasswordAsync(string email, string password)
		{
			var content = $"{{\"email\":\"{email}\",\"password\":\"{password}\",\"returnSecureToken\":true}}";

			return await this.SignInWithPostContentAsync(GooglePasswordUrl, content).ConfigureAwait(false);
		}

		/// <summary>
		/// Creates new user with given credentials.
		/// </summary>
		/// <param name="email"> The email. </param>
		/// <param name="password"> The password. </param>
		/// <returns> The <see cref="FirebaseAuth"/>. </returns>
		public async Task<FirebaseAuthLink> CreateUserWithEmailAndPasswordAsync(string email, string password)
		{
			var content = $"{{\"email\":\"{email}\",\"password\":\"{password}\",\"returnSecureToken\":true}}";

			return await this.SignInWithPostContentAsync(GoogleSignUpUrl, content).ConfigureAwait(false);
		}

		/// <summary>
		/// Sends user an email with a link to reset his password.
		/// </summary>
		/// <param name="email"> The email. </param>
		public async Task SendPasswordResetEmailAsync(string email)
		{
			var content = $"{{\"requestType\":\"PASSWORD_RESET\",\"email\":\"{email}\"}}";

			var response = await this.client.PostAsync(new Uri(string.Format(GooglePasswordResetUrl, this.authConfig.ApiKey)), new StringContent(content, Encoding.UTF8, "application/json")).ConfigureAwait(false);

			response.EnsureSuccessStatusCode();
		}

		/// <summary>
		/// Links the authenticated user represented by <see cref="auth"/> with an email and password. 
		/// </summary>
		/// <param name="auth"> The authenticated user to link with specified email and password. </param>
		/// <param name="email"> The email. </param>
		/// <param name="password"> The password. </param>
		/// <returns> The <see cref="FirebaseAuthLink"/>. </returns>
		public async Task<FirebaseAuthLink> LinkAccountsAsync(FirebaseAuth auth, string email, string password)
		{
			var content = $"{{\"idToken\":\"{auth.FirebaseToken}\",\"email\":\"{email}\",\"password\":\"{password}\",\"returnSecureToken\":true}}";

			return await this.SignInWithPostContentAsync(GoogleSetAccountUrl, content).ConfigureAwait(false);
		}

		/// <summary>
		/// Links the authenticated user represented by <see cref="auth"/> with and account from a third party provider.
		/// </summary>
		/// <param name="auth"> The auth. </param>
		/// <param name="authType"> The auth type.  </param>
		/// <param name="oauthAccessToken"> The access token retrieved from login provider of your choice. </param>
		/// <returns> The <see cref="FirebaseAuthLink"/>.  </returns>
		public async Task<FirebaseAuthLink> LinkAccountsAsync(FirebaseAuth auth, FirebaseAuthType authType, string oauthAccessToken)
		{
			var providerId = this.GetProviderId(authType);
			var content = $"{{\"idToken\":\"{auth.FirebaseToken}\",\"postBody\":\"access_token={oauthAccessToken}&providerId={providerId}\",\"requestUri\":\"http://localhost\",\"returnSecureToken\":true}}";

			return await this.SignInWithPostContentAsync(GoogleIdentityUrl, content).ConfigureAwait(false);
		}

		/// <summary>
		/// Disposes all allocated resources. 
		/// </summary>
		public void Dispose()
		{
			this.client.Dispose();
		}

		private async Task<FirebaseAuthLink> SignInWithPostContentAsync(string googleUrl, string postContent)
		{
			var response = await this.client.PostAsync(new Uri(string.Format(googleUrl, this.authConfig.ApiKey)), new StringContent(postContent, Encoding.UTF8, "application/json")).ConfigureAwait(false);
			var responseData = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

			if (!response.IsSuccessStatusCode)
			{
				var jsonReturn = JObject.Parse(responseData);
				var message = (string)jsonReturn["error"]["message"];

				// Login
				// Email address not found in database
				if (message.Equals("EMAIL_NOT_FOUND"))
				{
					throw new FirebaseInvalidEmailException("Email address not found");
				}
				// Login
				// Invalid password supplied
				else if (message.Equals("INVALID_PASSWORD"))
				{
					throw new FirebaseIncorrectPasswordException("Incorrect passord");
				}
				// New User
				// Email address already exists
				else if (message.Equals("EMAIL_EXISTS"))
				{
					throw new FirebaseUsedEmailException("Email address already exists");
				}
				// New User
				// Week Password
				else if (message.Contains("WEAK_PASSWORD"))
				{
					throw new FirebaseWeakPasswordException("Weak password, must be at least 6 characters");
				}
				// Just end on default status check
				else
				{
					response.EnsureSuccessStatusCode();
				}
			}

			var user = JsonConvert.DeserializeObject<User>(responseData);
			var auth = JsonConvert.DeserializeObject<FirebaseAuthLink>(responseData);

			auth.User = user;
			auth.AuthProvider = this;

			return auth;
		}

		private string GetProviderId(FirebaseAuthType authType)
		{
			switch (authType)
			{
				case FirebaseAuthType.Facebook:
					return "facebook.com";
				case FirebaseAuthType.Google:
					return "google.com";
				case FirebaseAuthType.Github:
					return "github.com";
				case FirebaseAuthType.Twitter:
					return "twitter.com";
				default: throw new NotImplementedException("");
			}
		}
	}
}


================================================
FILE: Auth/FirebaseAuthType.cs
================================================
namespace Firebase.Xamarin.Auth
{
    /// <summary>
    /// The type of authentication. 
    /// </summary>
    public enum FirebaseAuthType
    {
        /// <summary>
        /// The facebook auth.
        /// </summary>
        Facebook,

        /// <summary>
        /// The google auth.
        /// </summary>
        Google,

        /// <summary>
        /// The github auth.
        /// </summary>
        Github,

        /// <summary>
        /// The twitter auth. 
        /// </summary> 
        Twitter
    } 
}


================================================
FILE: Auth/FirebaseConfig.cs
================================================
namespace Firebase.Xamarin.Auth
{
    /// <summary>
    /// The auth config. 
    /// </summary>
    public class FirebaseConfig
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="FirebaseConfig"/> class.
        /// </summary>
        /// <param name="apiKey"> The api key of your Firebase app. </param>
        public FirebaseConfig(string apiKey)
        {
            this.ApiKey = apiKey;
        }
        
        /// <summary>
        /// Initializes a new instance of the <see cref="T:FirebaseConfig"/> class.
        /// </summary>
        /// <param name="apiKey">API key.</param>
        /// <param name="apiKeyForPushNotification">API key for push notification.</param>
        public FirebaseConfig(string apiKey, string apiKeyForPushNotification)
        {
            this.ApiKey = apiKey;
            this.ApiKeyForPushNotification = apiKeyForPushNotification;
        }

        /// <summary>
        /// Gets or sets the api key of your Firebase app. 
        /// </summary>
        public string ApiKey 
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the API key for push notification.
        /// </summary>
        /// <value>The API key for push notification.</value>
        public string ApiKeyForPushNotification
        {
            get;
            set;
        }
    }
}


================================================
FILE: Auth/IFirebaseAuthProvider.cs
================================================
namespace Firebase.Xamarin.Auth
{
    using System.Threading.Tasks;

    /// <summary>
    /// The auth token provider.
    /// </summary>
    public interface IFirebaseAuthProvider
    {
        /// <summary>
        /// Creates new user with given credentials.
        /// </summary>
        /// <param name="email"> The email. </param>
        /// <param name="password"> The password. </param>
        /// <returns> The <see cref="FirebaseAuthLink"/>. </returns>
        Task<FirebaseAuthLink> CreateUserWithEmailAndPasswordAsync(string email, string password);
        
        /// <summary>
        /// Sends user an email with a link to reset his password.
        /// </summary>
        /// <param name="email"> The email.  </param>
        /// <returns> The <see cref="Task"/>. </returns>
        Task SendPasswordResetEmailAsync(string email);

        /// <summary>
        /// Sign in user anonymously. He would still have a user id and access token generated, but name and other personal user properties will be null.
        /// </summary>
        /// <returns> The <see cref="FirebaseAuthLink"/>. </returns>
        Task<FirebaseAuthLink> SignInAnonymouslyAsync();

        /// <summary>
        /// Using the provided email and password, get the firebase auth with token and basic user credentials.
        /// </summary>
        /// <param name="email"> The email. </param>
        /// <param name="password"> The password. </param>
        /// <returns> The <see cref="FirebaseAuthLink"/>. </returns>
        Task<FirebaseAuthLink> SignInWithEmailAndPasswordAsync(string email, string password);

        /// <summary>
        /// Using the provided access token from third party auth provider (google, facebook...), get the firebase auth with token and basic user credentials.
        /// </summary>
        /// <param name="authType"> The auth type. </param>
        /// <param name="oauthAccessToken"> The access token retrieved from login provider of your choice. </param>
        /// <returns> The <see cref="FirebaseAuthLink"/>. </returns>
        Task<FirebaseAuthLink> SignInWithOAuthAsync(FirebaseAuthType authType, string oauthAccessToken);

        /// <summary>
        /// Links the authenticated user represented by <see cref="auth"/> with an email and password. 
        /// </summary>
        /// <param name="auth"> The authenticated user to link with specified email and password. </param>
        /// <param name="email"> The email. </param>
        /// <param name="password"> The password. </param>
        /// <returns> The <see cref="FirebaseAuthLink"/>. </returns>
        Task<FirebaseAuthLink> LinkAccountsAsync(FirebaseAuth auth, string email, string password);

        /// <summary>
        /// Links the authenticated user represented by <see cref="auth"/> with and account from a third party provider.
        /// </summary>
        /// <param name="auth"> The auth. </param>
        /// <param name="authType"> The auth type.  </param>
        /// <param name="oauthAccessToken"> The access token retrieved from login provider of your choice. </param>
        /// <returns> The <see cref="FirebaseAuthLink"/>.  </returns>
        Task<FirebaseAuthLink> LinkAccountsAsync(FirebaseAuth auth, FirebaseAuthType authType, string oauthAccessToken);
    }
}

================================================
FILE: Auth/User.cs
================================================
namespace Firebase.Xamarin.Auth
{
    using System.ComponentModel;

    using Newtonsoft.Json;

    /// <summary>
    /// Basic information about the logged in user.
    /// </summary>
    public class User
    {
        /// <summary>
        /// Gets or sets the local id.
        /// </summary>
        [JsonProperty("localId", DefaultValueHandling = DefaultValueHandling.Populate)]
        [DefaultValue("")]
        public string LocalId
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the federated id.
        /// </summary>
        [JsonProperty("federatedId", DefaultValueHandling = DefaultValueHandling.Populate)]
        [DefaultValue("")]
        public string FederatedId
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the first name.
        /// </summary>
        [JsonProperty("firstName", DefaultValueHandling = DefaultValueHandling.Populate)] 
        [DefaultValue("")]
        public string FirstName
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the last name.
        /// </summary>
        [JsonProperty("lastName", DefaultValueHandling = DefaultValueHandling.Populate)]
        [DefaultValue("")]
        public string LastName
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the display name.
        /// </summary>
        [JsonProperty("displayName", DefaultValueHandling = DefaultValueHandling.Populate)]
        [DefaultValue("")]
        public string DisplayName
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the email.
        /// </summary>
        [JsonProperty("email", DefaultValueHandling = DefaultValueHandling.Populate)]
        [DefaultValue("")]
        public string Email
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the photo url.
        /// </summary>
        [JsonProperty("photoUrl", DefaultValueHandling = DefaultValueHandling.Populate)]
        [DefaultValue("")]
        public string PhotoUrl
        {
            get;
            set;
        }
    }
}


================================================
FILE: Database/FirebaseClient.cs
================================================
namespace Firebase.Xamarin.Database
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;

    using Firebase.Xamarin.Database.Offline;
    using Firebase.Xamarin.Database.Query;

    /// <summary>
    /// Firebase client which acts as an entry point to the online database.
    /// </summary>
    public class FirebaseClient
    {
        internal readonly Func<Type, string, IDictionary<string, OfflineEntry>> OfflineDatabaseFactory;
        internal readonly Func<Task<string>> AuthTokenAsyncFactory;

        private readonly string baseUrl;

        /// <summary>
        /// Initializes a new instance of the <see cref="FirebaseClient"/> class.
        /// </summary>
        /// <param name="baseUrl"> The base url. </param>
        public FirebaseClient(string baseUrl) : this(baseUrl, (t, s) => new Dictionary<string, OfflineEntry>())
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FirebaseClient"/> class.
        /// </summary>
        /// <param name="baseUrl"> The base url. </param>
        /// <param name="offlineDatabaseFactory"> Offline database. </param>  
        public FirebaseClient(string baseUrl, Func<Type, string, IDictionary<string, OfflineEntry>> offlineDatabaseFactory)
        {
            this.OfflineDatabaseFactory = offlineDatabaseFactory;

            this.baseUrl = baseUrl;

            if (!this.baseUrl.EndsWith("/"))
            {
                this.baseUrl += "/";
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FirebaseClient"/> class.
        /// </summary>
        /// <param name="baseUrl"> The base url. </param>
        /// <param name="authTokenAsyncFactory"> Factory which returns valid firebase auth token. </param>
        public FirebaseClient(string baseUrl, Func<Task<string>> authTokenAsyncFactory) 
            : this(baseUrl, authTokenAsyncFactory, (t, s) => new Dictionary<string, OfflineEntry>())
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FirebaseClient"/> class.
        /// </summary>
        /// <param name="baseUrl"> The base url. </param>
        /// <param name="authTokenAsyncFactory"> Factory which returns valid firebase auth token. </param>
        /// <param name="offlineDatabaseFactory"> Offline database. </param>   
        public FirebaseClient(string baseUrl, Func<Task<string>> authTokenAsyncFactory, Func<Type, string, IDictionary<string, OfflineEntry>> offlineDatabaseFactory) 
            : this(baseUrl, offlineDatabaseFactory)
        {
            this.AuthTokenAsyncFactory = authTokenAsyncFactory;
        }

        /// <summary>
        /// Queries for a child of the data root.
        /// </summary>
        /// <param name="resourceName"> Name of the child. </param>
        /// <returns> <see cref="ChildQuery"/>. </returns>
        public ChildQuery Child(string resourceName)
        {
            return new ChildQuery(this, () => this.baseUrl + resourceName);
        }
    }
}


================================================
FILE: Database/FirebaseKeyGenerator.cs
================================================
namespace Firebase.Xamarin.Database
{
    using System;
    using System.Text;

    /// <summary>
    /// Offline key generator which mimics the official Firebase generators. 
    /// Credit: https://github.com/bubbafat/FirebaseSharp/blob/master/src/FirebaseSharp.Portable/FireBasePushIdGenerator.cs
    /// </summary>
    public class FirebaseKeyGenerator 
    {
        // Modeled after base64 web-safe chars, but ordered by ASCII.
        private const string PushCharsString = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
        private static readonly char[] PushChars;
        private static readonly DateTimeOffset Epoch = new DateTimeOffset(1970, 1, 1, 0, 0, 0, 0, TimeSpan.Zero);

        private static readonly Random random = new Random();
        private static readonly byte[] lastRandChars = new byte[12];

        // Timestamp of last push, used to prevent local collisions if you push twice in one ms.
        private static long lastPushTime;

        static FirebaseKeyGenerator()
        {
            PushChars = Encoding.UTF8.GetChars(Encoding.UTF8.GetBytes(PushCharsString));
        }

        /// <summary>
        /// Returns next firebase key based on current time.  
        /// </summary>
        /// <returns>
        /// The <see cref="string"/>. </returns>
        public static string Next()
        {
            // We generate 72-bits of randomness which get turned into 12 characters and
            // appended to the timestamp to prevent collisions with other clients. We store the last
            // characters we generated because in the event of a collision, we'll use those same
            // characters except "incremented" by one.
            var id = new StringBuilder(20);
            var now = (long)(DateTimeOffset.Now - Epoch).TotalMilliseconds;
            var duplicateTime = now == lastPushTime;
            lastPushTime = now;

            var timeStampChars = new char[8];
            for (int i = 7; i >= 0; i--)
            {
                var index = (int)(now % PushChars.Length);
                timeStampChars[i] = PushChars[index];
                now = (long)Math.Floor((double)now / PushChars.Length);
            }

            if (now != 0)
            {
                throw new Exception("We should have converted the entire timestamp.");
            }

            id.Append(timeStampChars);

            if (!duplicateTime)
            {
                for (int i = 0; i < 12; i++)
                {
                    lastRandChars[i] = (byte)random.Next(0, PushChars.Length);
                }
            }
            else
            {
                // If the timestamp hasn't changed since last push, use the same random number,
                // except incremented by 1.
                var lastIndex = 11;
                for (; lastIndex >= 0 && lastRandChars[lastIndex] == PushChars.Length - 1; lastIndex--)
                {
                    lastRandChars[lastIndex] = 0;
                }

                lastRandChars[lastIndex]++;
            }

            for (int i = 0; i < 12; i++)
            {
                id.Append(PushChars[lastRandChars[i]]);
            }

            if (id.Length != 20)
            {
                throw new Exception("Length should be 20.");
            }

            return id.ToString();
        }
    }
}


================================================
FILE: Database/FirebaseObject.cs
================================================
namespace Firebase.Xamarin.Database
{
    /// <summary>
    /// Holds the object of type <typeparam name="T" /> along with its key. 
    /// </summary>
    /// <typeparam name="T"> Type of the underlying object. </typeparam> 
    public class FirebaseObject<T> 
    {
        internal FirebaseObject(string key, T obj)
        {
            this.Key = key;
            this.Object = obj;
        }

        /// <summary>
        /// Gets the key of <see cref="Object"/>.
        /// </summary>
        public string Key
        {
            get;
        }

        /// <summary>
        /// Gets the underlying object.
        /// </summary>
        public T Object
        {
            get;
        }
    }
}


================================================
FILE: Database/GlobalSuppressions.cs
================================================

// This file is used by Code Analysis to maintain SuppressMessage 
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given 
// a specific target and scoped to a namespace, type, member, etc.



================================================
FILE: Database/Http/HttpClientExtensions.cs
================================================
namespace Firebase.Xamarin.Database.Http
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net.Http;
    using System.Threading.Tasks;

    using Newtonsoft.Json;

    /// <summary>
    /// The http client extensions for object deserializations.
    /// </summary>
    internal static class HttpClientExtensions
    {
        /// <summary>
        /// The get object collection async.
        /// </summary>
        /// <param name="client"> The client. </param>
        /// <param name="requestUri"> The request uri. </param>  
        /// <typeparam name="T"> The type of entities the collection should contain. </typeparam>
        /// <returns> The <see cref="Task"/>. </returns>
        public static async Task<IReadOnlyCollection<FirebaseObject<T>>> GetObjectCollectionAsync<T>(this HttpClient client, string requestUri)
        {
            var data = await client.GetStringAsync(requestUri).ConfigureAwait(false);
            var dictionary = JsonConvert.DeserializeObject<Dictionary<string, T>>(data);

            if (dictionary == null)
            {
                return new FirebaseObject<T>[0];
            }

            return dictionary.Select(item => new FirebaseObject<T>(item.Key, item.Value)).ToList();
        }

        /// <summary>
        /// The get object collection async.
        /// </summary>
        /// <param name="data"> The json data. </param>
        /// <param name="elementType"> The type of entities the collection should contain. </param>
        /// <returns> The <see cref="Task"/>.  </returns>
        public static IEnumerable<FirebaseObject<object>> GetObjectCollection(this string data, Type elementType)
        {
            var dictionaryType = typeof(Dictionary<,>).MakeGenericType(typeof(string), elementType);
            var dictionary = JsonConvert.DeserializeObject(data, dictionaryType) as IDictionary;

            if (dictionary == null)
            {
                yield break;
            }

            foreach (DictionaryEntry item in dictionary)
            {
                yield return new FirebaseObject<object>((string)item.Key, item.Value);
            }
        }
    }
}


================================================
FILE: Database/Http/PostResult.cs
================================================
namespace Firebase.Xamarin.Database.Http
{
    /// <summary>
    /// Represents data returned after a successful POST to firebase server.
    /// </summary>
    public class PostResult
    {
        /// <summary>
        /// Gets or sets the generated key after a successful post. 
        /// </summary>
        public string Name
        {
            get;
            set;
        }
    }
}


================================================
FILE: Database/ObservableExtensions.cs
================================================
namespace Firebase.Xamarin.Database
{
    using System;
    using System.Collections.ObjectModel;

    using Firebase.Xamarin.Database.Streaming;

    /// <summary>
    /// Extensions for <see cref="IObservable{T}"/>.
    /// </summary>
    public static class ObservableExtensions
    {
        /// <summary>
        /// Starts observing on given firebase observable and propagates event into an <see cref="ObservableCollection{T}"/>.
        /// </summary>
        /// <param name="observable"> The observable. </param>
        /// <typeparam name="T"> Type of entity. </typeparam>
        /// <returns> The <see cref="ObservableCollection{T}"/>. </returns> 
        public static ObservableCollection<T> AsObservableCollection<T>(this IObservable<FirebaseEvent<T>> observable)
        {
            var collection = new ObservableCollection<T>();

            observable.Subscribe(f =>
            {
                if (f.EventType == FirebaseEventType.InsertOrUpdate)
                {
                    var i = collection.IndexOf(f.Object);
                    if (i >= 0)
                    {
                        collection.RemoveAt(i);
                    }

                    collection.Add(f.Object);
                }
                else
                {
                    collection.Remove(f.Object);
                }
            });

            return collection;
        }
    }
}


================================================
FILE: Database/Offline/ExceptionEventArgs.cs
================================================
namespace Firebase.Xamarin.Database.Offline
{
    using System;

    /// <summary>
    /// Event args holding the <see cref="Exception"/> object.
    /// </summary>
    public class ExceptionEventArgs : EventArgs
    {
        public readonly Exception Exception;

        /// <summary>
        /// Initializes a new instance of the <see cref="ExceptionEventArgs"/> class.
        /// </summary>
        /// <param name="exception"> The exception. </param>
        public ExceptionEventArgs(Exception exception)
        {
            this.Exception = exception;
        }
    }
}


================================================
FILE: Database/Offline/OfflineCacheAdapter.cs
================================================
namespace Firebase.Xamarin.Database.Offline
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;

    internal class OfflineCacheAdapter<TKey, T> : IDictionary<string, T>, IDictionary 
    {
        private readonly IDictionary<string, OfflineEntry> database;

        public OfflineCacheAdapter(IDictionary<string, OfflineEntry> database)
        {
            this.database = database;
        }

        public void CopyTo(Array array, int index)
        {
            throw new NotImplementedException();
        }

        public int Count => this.database.Count;

        public bool IsSynchronized { get; }

        public object SyncRoot { get; }

        public bool IsReadOnly => this.database.IsReadOnly;

        object IDictionary.this[object key]
        {
            get
            {
                return this.database[key.ToString()].Deserialize<T>();
            }

            set
            {
                this.database[key.ToString()] = new OfflineEntry(key.ToString(), value, 1, SyncOptions.None);
            }
        }

        public ICollection<string> Keys => this.database.Keys;

        ICollection IDictionary.Values { get; }

        ICollection IDictionary.Keys { get; }

        public ICollection<T> Values => this.database.Values.Select(o => o.Deserialize<T>()).ToList();

        public T this[string key]
        {
            get
            {
                return this.database[key].Deserialize<T>();
            }

            set
            {
                this.database[key] = new OfflineEntry(key, value, 1, SyncOptions.None);
            }
        }

        public bool Contains(object key)
        {
            return this.ContainsKey(key.ToString());
        }

        IDictionaryEnumerator IDictionary.GetEnumerator()
        {
            throw new NotImplementedException();
        }

        public void Remove(object key)
        {
            this.Remove(key.ToString());
        }

        public bool IsFixedSize => false;

        public IEnumerator<KeyValuePair<string, T>> GetEnumerator()
        {
            return this.database.Select(d => new KeyValuePair<string, T>(d.Key, d.Value.Deserialize<T>())).GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        public void Add(KeyValuePair<string, T> item)
        {
            this.Add(item.Key, item.Value);
        }

        public void Add(object key, object value)
        {
            this.Add(key.ToString(), (T)value);
        }

        public void Clear()
        {
            this.database.Clear();
        }

        public bool Contains(KeyValuePair<string, T> item)
        {
            return this.ContainsKey(item.Key);
        }

        public void CopyTo(KeyValuePair<string, T>[] array, int arrayIndex)
        {
            throw new NotImplementedException();
        }

        public bool Remove(KeyValuePair<string, T> item)
        {
            return this.database.Remove(item.Key);
        }

        public void Add(string key, T value)
        {
            this.database.Add(key, new OfflineEntry(key, value, 1, SyncOptions.None));
        }

        public bool ContainsKey(string key)
        {
            return this.database.ContainsKey(key);
        }

        public bool Remove(string key)
        {
            return this.database.Remove(key);
        }

        public bool TryGetValue(string key, out T value)
        {
            OfflineEntry val;

            if (this.database.TryGetValue(key, out val))
            {
                value = val.Deserialize<T>();
                return true;
            }

            value = default(T);
            return false;
        }
    }
}


================================================
FILE: Database/Offline/OfflineEntry.cs
================================================
namespace Firebase.Xamarin.Database.Offline
{
    using System;

    using Newtonsoft.Json;

    /// <summary>
    /// Represents an object stored in offline storage.
    /// </summary>
    public class OfflineEntry
    {
        private object dataInstance;

        /// <summary>
        /// Initializes a new instance of the <see cref="OfflineEntry"/> class.
        /// </summary>
        /// <param name="key"> The key. </param>
        /// <param name="obj"> The object. </param>
        /// <param name="priority"> The priority. Objects with higher priority will be synced first. Higher number indicates higher priority. </param>  
        /// <param name="syncOptions"> The sync options. </param>
        public OfflineEntry(string key, object obj, int priority, SyncOptions syncOptions = SyncOptions.Push)
        {
            this.Key = key;
            this.Priority = priority;
            this.Data = JsonConvert.SerializeObject(obj);
            this.Timestamp = DateTime.UtcNow;
            this.SyncOptions = syncOptions;

            this.dataInstance = obj;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="OfflineEntry"/> class.
        /// </summary>
        public OfflineEntry() 
        {
        }

        /// <summary>
        /// Gets or sets the key of this entry.
        /// </summary>
        public string Key
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the priority. Objects with higher priority will be synced first. Higher number indicates higher priority. 
        /// </summary>
        public int Priority 
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the timestamp when this entry was last touched.
        /// </summary>
        public DateTime Timestamp
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the <see cref="SyncOptions"/> which define what sync state this entry is in.
        /// </summary>
        public SyncOptions SyncOptions
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets serialized JSON data. 
        /// </summary>
        public string Data
        {
            get;
            set;
        }

        /// <summary>
        /// Deserializes <see cref="Data"/> into <typeparamref name="T"/>. The result is cached.
        /// </summary>
        /// <typeparam name="T"> Type of object to deserialize into. </typeparam>
        /// <returns> Instance of <typeparamref name="T"/>. </returns>
        public T Deserialize<T>()
        {
            return (T)(this.dataInstance ?? (this.dataInstance = JsonConvert.DeserializeObject<T>(this.Data)));
        }
    }
}


================================================
FILE: Database/Offline/RealtimeDatabase.cs
================================================
namespace Firebase.Xamarin.Database.Offline
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reactive.Linq;
    using System.Reactive.Subjects;
    using System.Threading;
    using System.Threading.Tasks;

    using Firebase.Xamarin.Database.Query;
    using Firebase.Xamarin.Database.Streaming;

    /// <summary>
    /// The real-time database which synchronizes online and offline data. 
    /// </summary>
    /// <typeparam name="T"> Type of entities. </typeparam>
    public partial class RealtimeDatabase<T> where T : class
    {
        private readonly ChildQuery childQuery;
        private readonly bool streamChanges;
        private readonly IDictionary<string, OfflineEntry> database;
        private readonly string elementRoot;
        private readonly Subject<FirebaseEvent<T>> subject;

        private IObservable<FirebaseEvent<T>> observable;

        /// <summary>
        /// Initializes a new instance of the <see cref="RealtimeDatabase{T}"/> class.
        /// </summary>
        /// <param name="childQuery"> The child query.  </param>
        /// <param name="elementRoot"> The element Root. </param>
        /// <param name="offlineDatabaseFactory"> The offline database factory.  </param>
        /// <param name="filenameModifier"> Custom string which will get appended to the file name.  </param>
        /// <param name="streamChanges"> Specifies whether changes should be streamed from the server.  </param>
        public RealtimeDatabase(ChildQuery childQuery, string elementRoot, Func<Type, string, IDictionary<string, OfflineEntry>> offlineDatabaseFactory, string filenameModifier, bool streamChanges)
        {
            this.childQuery = childQuery;
            this.elementRoot = elementRoot;
            this.streamChanges = streamChanges;
            this.database = offlineDatabaseFactory(typeof(T), filenameModifier);
            this.subject = new Subject<FirebaseEvent<T>>();

            Task.Factory.StartNew(this.SynchronizeThread, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);
        }

        /// <summary>
        /// Event raised whenever an exception is thrown in the synchronization thread. Exception thrown in there are swallowed, so this event is the only way to get to them. 
        /// </summary>
        public event EventHandler<ExceptionEventArgs> SyncExceptionThrown;

        /// <summary>
        /// Overwrites existing object with given key.
        /// </summary>
        /// <param name="key"> The key. </param>
        /// <param name="obj"> The object to set. </param>
        /// <param name="priority"> The priority. Objects with higher priority will be synced first. Higher number indicates higher priority. </param>
        public void Put(string key, T obj, int priority = 1)
        {
            this.SetAndRaise(key, new OfflineEntry(key, obj, priority));
        }

        /// <summary>
        /// Adds a new entity to the database.
        /// </summary>
        /// <param name="obj"> The object to add.  </param>
        /// <param name="priority"> The priority. Objects with higher priority will be synced first. Higher number indicates higher priority. </param>
        /// <returns> The generated key for this object. </returns>
        public string Post(T obj, int priority = 1)
        {
            var key = FirebaseKeyGenerator.Next();

            this.SetAndRaise(key, new OfflineEntry(key, obj, priority));

            return key;
        }

        /// <summary>
        /// Deletes the entity with the given key.
        /// </summary>
        /// <param name="key"> The key. </param>
        /// <param name="priority"> The priority. Objects with higher priority will be synced first. Higher number indicates higher priority. </param> 
        public void Delete(string key, int priority = 1)
        {
            this.SetAndRaise(key, new OfflineEntry(key, null, priority));
        }

        /// <summary>
        /// Fetches an object with the given key and adds it to the database.
        /// </summary>
        /// <param name="key"> The key. </param>
        /// <param name="priority"> The priority. Objects with higher priority will be synced first. Higher number indicates higher priority. </param>
        public void Pull(string key, int priority = 1)
        {
            if (!this.database.ContainsKey(key))
            {
                this.database[key] = new OfflineEntry(key, null, priority, SyncOptions.Pull);
            }
            else
            {
                this.database[key].SyncOptions = SyncOptions.Pull;
            }
        }

        /// <summary> 
        /// Starts observing the real-time database. Events will be fired both when change is done locally and remotely.
        /// </summary> 
        /// <returns> Stream of <see cref="FirebaseEvent{T}"/>. </returns>
        public IObservable<FirebaseEvent<T>> AsObservable()
        {
            if (this.observable == null)
            { 
                var initialData = this.database
                    .Where(kvp => !string.IsNullOrEmpty(kvp.Value.Data) && kvp.Value.Data != "null")
                    .Select(kvp => new FirebaseEvent<T>(kvp.Key, kvp.Value.Deserialize<T>(), FirebaseEventType.InsertOrUpdate))
                    .ToList().ToObservable();

                this.observable = Observable
                    .Create<FirebaseEvent<T>>(observer => this.InitializeStreamingSubscription(observer))
                    .Merge(initialData)
                    .Merge(this.subject)
                    .Replay()
                    .RefCount();
            }

            return this.observable;
        }   

        private IDisposable InitializeStreamingSubscription(IObserver<FirebaseEvent<T>> observer)
        {
            return this.streamChanges 
                ? new FirebaseSubscription<T>(observer, this.childQuery.OrderByKey().StartAt(() => this.GetLatestKey()), this.elementRoot, new FirebaseCache<T>(new OfflineCacheAdapter<string, T>(this.database))).Run() 
                : Observable.Never<string>().Subscribe();
        }

        private void SetAndRaise(string key, OfflineEntry obj)
        {
            this.database[key] = obj;
            this.subject.OnNext(new FirebaseEvent<T>(key, obj?.Deserialize<T>(), string.IsNullOrEmpty(obj?.Data) ? FirebaseEventType.Delete : FirebaseEventType.InsertOrUpdate));
        }

        private async void SynchronizeThread()
        {
            while (true)
            {
                try
                {
                    var validEntries = this.database.Where(e => e.Value != null);
                    await this.PullEntriesAsync(validEntries.Where(kvp => kvp.Value.SyncOptions == SyncOptions.Pull));
                    await this.PushEntriesAsync(validEntries.Where(kvp => kvp.Value.SyncOptions == SyncOptions.Push));
                }
                catch (Exception ex)
                {
                    this.SyncExceptionThrown?.Invoke(this, new ExceptionEventArgs(ex));
                }

                await Task.Delay(1000);
            }
        }

        private string GetLatestKey()
        {
            return this.database.OrderBy(o => o.Key, StringComparer.Ordinal).LastOrDefault().Key;
        }

        private async Task PushEntriesAsync(IEnumerable<KeyValuePair<string, OfflineEntry>> pushEntries)
        {
            var groups = pushEntries.GroupBy(pair => pair.Value.Priority).OrderByDescending(kvp => kvp.Key);

            foreach (var group in groups)
            {
                var tasks = group.Select(kvp => this.childQuery.Child(kvp.Key).PutAsync(kvp.Value.Deserialize<T>())).ToList();

                await Task.WhenAll(tasks);

                this.ResetSyncOptions(group.Select(s => s.Key));
            }
        }

        private async Task PullEntriesAsync(IEnumerable<KeyValuePair<string, OfflineEntry>> pullEntries)
        {
            var taskGroups = pullEntries.GroupBy(pair => pair.Value.Priority).OrderByDescending(kvp => kvp.Key);

            foreach (var group in taskGroups)
            {
                var tasks = group.Select(pair => new { Key = pair.Key, Task = this.childQuery.Child(pair.Key).OnceSingleAsync<T>(), Priority = pair.Value.Priority }).ToList();

                await Task.WhenAll(tasks.Select(t => t.Task));

                foreach (var task in tasks)
                {
                    this.SetAndRaise(task.Key, new OfflineEntry(task.Key, task.Task.Result, task.Priority, SyncOptions.None));
                }
            }
        }

        private void ResetSyncOptions(IEnumerable<string> entries)
        {
            foreach (var key in entries)
            {
                var item = this.database[key];
                item.SyncOptions = SyncOptions.None;
                this.database[key] = item;
            }
        }
    }
}


================================================
FILE: Database/Offline/SyncOptions.cs
================================================
namespace Firebase.Xamarin.Database.Offline
{
    /// <summary>
    /// Specifies type of sync requested for given data.
    /// </summary>
    public enum SyncOptions
    {
        /// <summary>
        /// No sync needed for given data. 
        /// </summary>
        None,

        /// <summary>
        /// Data should be pulled from firebase.
        /// </summary>
        Pull,

        /// <summary>
        /// Data should be pushed to firebase.
        /// </summary>
        Push
    }
}


================================================
FILE: Database/Properties/AssemblyInfo.cs
================================================
using System.Resources;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Firebase.Database")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Step Up Labs, Inc.")]
[assembly: AssemblyProduct("Firebase.Database")]
[assembly: AssemblyCopyright("Copyright © Step Up Labs, Inc. 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: InternalsVisibleTo("Firebase.Database.Tests")]


================================================
FILE: Database/Query/AuthQuery.cs
================================================
namespace Firebase.Xamarin.Database.Query
{
    using System;

    /// <summary>
    /// Represents an auth parameter in firebase query, e.g. "?auth=xyz".
    /// </summary>
    public class AuthQuery : ParameterQuery
    {
        private readonly Func<string> tokenFactory;

        /// <summary>
        /// Initializes a new instance of the <see cref="AuthQuery"/> class.
        /// </summary>
        /// <param name="parent"> The parent.  </param>  
        /// <param name="tokenFactory"> The authentication token factory. </param>
        /// <param name="client"> The owner. </param>
        public AuthQuery(FirebaseQuery parent, Func<string> tokenFactory, FirebaseClient client) : base(parent, () => "auth", client)
        {
            this.tokenFactory = tokenFactory;
        }

        /// <summary>
        /// Build the url parameter value of this child. 
        /// </summary>
        /// <param name="child"> The child of this child. </param>
        /// <returns> The <see cref="string"/>. </returns>
        protected override string BuildUrlParameter(FirebaseQuery child)
        {
            return this.tokenFactory();
        }
    }
}


================================================
FILE: Database/Query/ChildQuery.cs
================================================
namespace Firebase.Xamarin.Database.Query
{
    using System;
	using Firebase.Xamarin.Database;
    using Firebase.Xamarin.Database.Offline;

    /// <summary>
    /// Firebase query which references the child of current node.
    /// </summary>
    public class ChildQuery : FirebaseQuery
    {
        private readonly Func<string> pathFactory;

        /// <summary>
        /// Initializes a new instance of the <see cref="ChildQuery"/> class.
        /// </summary>
        /// <param name="parent"> The parent.  </param>
        /// <param name="pathFactory"> The path to the child node.  </param>
        /// <param name="client"> The owner. </param>
        public ChildQuery(FirebaseQuery parent, Func<string> pathFactory, FirebaseClient client)
            : base(parent, client)
        {
            this.pathFactory = pathFactory;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ChildQuery"/> class.
        /// </summary>
        /// <param name="client"> The client. </param>
        /// <param name="pathFactory"> The path to the child node.  </param>
        public ChildQuery(FirebaseClient client, Func<string> pathFactory)
            : this(null, pathFactory, client)
        {
        }

        /// <summary>
        /// The as offline database.
        /// </summary>
        /// <typeparam name="T"> Type of elements. </typeparam>
        /// <param name="filenameModifier"> Custom string which will get appended to the file name. </param>
        /// <param name="elementRoot"> Optional custom root element of received json items. </param>
        /// <param name="streamChanges"> Specifies whether changes should be streamed from the server. </param> 
        /// <returns> The <see cref="RealtimeDatabase{T}"/>. </returns>
        public RealtimeDatabase<T> AsRealtimeDatabase<T>(string filenameModifier, string elementRoot = "", bool streamChanges = true) where T : class
        {
            return new RealtimeDatabase<T>(this, elementRoot, this.Client.OfflineDatabaseFactory, filenameModifier, streamChanges);
        }

        /// <summary>
        /// Build the url segment of this child.
        /// </summary>
        /// <param name="child"> The child of this child. </param>
        /// <returns> The <see cref="string"/>. </returns>
        protected override string BuildUrlSegment(FirebaseQuery child)
        {
            var s = this.pathFactory();

            if (s != string.Empty && !s.EndsWith("/"))
            {
                s += '/';
            }

            if (!(child is ChildQuery))
            {
                return s + ".json";
            }

            return s;
        }
    }
}


================================================
FILE: Database/Query/FilterQuery.cs
================================================
namespace Firebase.Xamarin.Database.Query 
{
    using System;
    using System.Globalization;

    /// <summary>
    /// Represents a firebase filtering query, e.g. "?LimitToLast=10".
    /// </summary>
    public class FilterQuery : ParameterQuery 
    {
        private readonly Func<string> valueFactory;
        private readonly Func<double> doubleValueFactory;

        /// <summary>
        /// Initializes a new instance of the <see cref="FilterQuery"/> class.
        /// </summary>
        /// <param name="parent"> The parent. </param>
        /// <param name="filterFactory"> The filter. </param>
        /// <param name="valueFactory"> The value for filter. </param>
        /// <param name="client"> The owning client. </param>  
        public FilterQuery(FirebaseQuery parent, Func<string> filterFactory, Func<string> valueFactory, FirebaseClient client)
            : base(parent, filterFactory, client)
        {
            this.valueFactory = valueFactory;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FilterQuery"/> class.
        /// </summary>
        /// <param name="parent"> The parent. </param>
        /// <param name="filterFactory"> The filter. </param>
        /// <param name="valueFactory"> The value for filter. </param>
        /// <param name="client"> The owning client. </param>
        public FilterQuery(FirebaseQuery parent, Func<string> filterFactory, Func<double> valueFactory, FirebaseClient client)
            : base(parent, filterFactory, client)
        {
            this.doubleValueFactory = valueFactory;
        }

        /// <summary>
        /// The build url parameter.
        /// </summary>
        /// <param name="child"> The child. </param> 
        /// <returns> Url parameter part of the resulting path. </returns> 
        protected override string BuildUrlParameter(FirebaseQuery child)
        {
            if (this.valueFactory != null)
            {
                return $"\"{this.valueFactory()}\"";
            }
            else if (this.doubleValueFactory != null)
            {
                return this.doubleValueFactory().ToString(CultureInfo.InvariantCulture);
            }

            return string.Empty;
        }
    }
}


================================================
FILE: Database/Query/FirebaseQuery.cs
================================================
namespace Firebase.Xamarin.Database.Query
{
    using System;
    using System.Collections.Generic;
    using System.Net.Http;
    using System.Reactive.Linq;
    using System.Threading.Tasks;

    using Firebase.Xamarin.Database.Http;
    using Firebase.Xamarin.Database.Offline;
    using Firebase.Xamarin.Database.Streaming;

    using Newtonsoft.Json;

    /// <summary>
    /// Represents a firebase query. 
    /// </summary>
    public abstract class FirebaseQuery : IFirebaseQuery, IDisposable
    {
        protected readonly FirebaseQuery Parent;
         
        private HttpClient client;

        /// <summary> 
        /// Initializes a new instance of the <see cref="FirebaseQuery"/> class.
        /// </summary>
        /// <param name="parent"> The parent of this query. </param>
        /// <param name="client"> The owning client. </param>
        protected FirebaseQuery(FirebaseQuery parent, FirebaseClient client)
        {
            this.Client = client;
            this.Parent = parent;
        }

        /// <summary>
        /// Gets the client.
        /// </summary>
        public FirebaseClient Client
        {
            get;
        }

        /// <summary>
        /// Queries the firebase server once returning collection of items.
        /// </summary>
        /// <typeparam name="T"> Type of elements. </typeparam>
        /// <returns> Collection of <see cref="FirebaseObject{T}"/> holding the entities returned by server. </returns>
        public async Task<IReadOnlyCollection<FirebaseObject<T>>> OnceAsync<T>()
        {
            var path = await this.BuildUrlAsync().ConfigureAwait(false);

            using (var client = new HttpClient())
            {
                return await client.GetObjectCollectionAsync<T>(path).ConfigureAwait(false);
            }
        }


        /// <summary>
        /// Assumes given query is pointing to a single object of type <typeparamref name="T"/> and retrieves it.
        /// </summary>
        /// <typeparam name="T"> Type of elements. </typeparam>
        /// <returns> Single object of type <typeparamref name="T"/>. </returns>
        public async Task<T> OnceSingleAsync<T>()
        {
            var path = await this.BuildUrlAsync().ConfigureAwait(false);

            using (var client = new HttpClient())
            {
                var data = await client.GetStringAsync(path).ConfigureAwait(false);
                return JsonConvert.DeserializeObject<T>(data);
            }
        }

        /// <summary>
        /// Starts observing this query watching for changes real time sent by the server.
        /// </summary>
        /// <typeparam name="T"> Type of elements. </typeparam>
        /// <param name="elementRoot"> Optional custom root element of received json items. </param>
        /// <returns> Observable stream of <see cref="FirebaseEvent{T}"/>. </returns>
        public IObservable<FirebaseEvent<T>> AsObservable<T>(string elementRoot = "")
        {
            return Observable.Create<FirebaseEvent<T>>(observer => new FirebaseSubscription<T>(observer, this, elementRoot, new FirebaseCache<T>()).Run());
        }

        /// <summary>
        /// Builds the actual URL of this query.
        /// </summary>
        /// <returns> The <see cref="string"/>. </returns>
        public async Task<string> BuildUrlAsync()
        {
            // if token factory is present on the parent then use it to generate auth token
            if (this.Client.AuthTokenAsyncFactory != null)
            {
                var token = await this.Client.AuthTokenAsyncFactory().ConfigureAwait(false);
                return this.WithAuth(token).BuildUrl(null);
            }

            return this.BuildUrl(null);
        }

        /// <summary>
        /// Posts given object to repository.
        /// </summary>
        /// <param name="obj"> The object. </param> 
        /// <param name="generateKeyOffline"> Specifies whether the key should be generated offline instead of online. </param> 
        /// <typeparam name="T"> Type of <see cref="obj"/> </typeparam>
        /// <returns> Resulting firebase object with populated key. </returns>
        public async Task<FirebaseObject<T>> PostAsync<T>(T obj, bool generateKeyOffline = true)
        {
            // post generates a new key server-side, while put can be used with an already generated local key
            if (generateKeyOffline)
            {
                var key = FirebaseKeyGenerator.Next();
                await new ChildQuery(this, () => key, this.Client).PutAsync(obj).ConfigureAwait(false);

                return new FirebaseObject<T>(key, obj);
            }
            else
            {
                var c = this.GetClient();
                var data = await this.SendAsync(c, obj, HttpMethod.Post).ConfigureAwait(false);
                var result = JsonConvert.DeserializeObject<PostResult>(data);

                return new FirebaseObject<T>(result.Name, obj);
            }
        }

        /// <summary>
        /// Patches data at given location instead of overwriting them. 
        /// </summary> 
        /// <param name="obj"> The object. </param>  
        /// <typeparam name="T"> Type of <see cref="obj"/> </typeparam>
        /// <returns> The <see cref="Task"/>. </returns>
        public async Task PatchAsync<T>(T obj)
        {
            var c = this.GetClient();

            await this.SendAsync(c, obj, new HttpMethod("PATCH")).ConfigureAwait(false);
        }

        /// <summary>
        /// Sets or overwrites data at given location. 
        /// </summary> 
        /// <param name="obj"> The object. </param>  
        /// <typeparam name="T"> Type of <see cref="obj"/> </typeparam>
        /// <returns> The <see cref="Task"/>. </returns>
        public async Task PutAsync<T>(T obj)
        {
            var c = this.GetClient();

            await this.SendAsync(c, obj, HttpMethod.Put).ConfigureAwait(false);
        }

        /// <summary>
        /// Deletes data from given location.
        /// </summary>
        /// <returns> The <see cref="Task"/>. </returns>
        public async Task DeleteAsync()
        {
            var c = this.GetClient();
            var url = await this.BuildUrlAsync().ConfigureAwait(false);
            var result = await c.DeleteAsync(url).ConfigureAwait(false);

            result.EnsureSuccessStatusCode();
        }

        /// <summary>
        /// Disposes this instance.  
        /// </summary>
        public void Dispose()
        {
            this.client?.Dispose();
        }

        /// <summary>
        /// Build the url segment of this child.
        /// </summary>
        /// <param name="child"> The child of this query. </param>
        /// <returns> The <see cref="string"/>. </returns>
        protected abstract string BuildUrlSegment(FirebaseQuery child);

        private string BuildUrl(FirebaseQuery child)
        {
            var url = this.BuildUrlSegment(child);

            if (this.Parent != null)
            {
                url = this.Parent.BuildUrl(this) + url;
            }

            return url;
        }

        private HttpClient GetClient()
        {
            if (this.client == null)
            {
                this.client = new HttpClient();
            }

            return this.client;
        }

        private async Task<string> SendAsync<T>(HttpClient client, T obj, HttpMethod method)
        {
            var url = await this.BuildUrlAsync().ConfigureAwait(false);
            var message = new HttpRequestMessage(method, url)
            {
                Content = new StringContent(JsonConvert.SerializeObject(obj))
            };

            var result = await client.SendAsync(message).ConfigureAwait(false);

            result.EnsureSuccessStatusCode();

            return await result.Content.ReadAsStringAsync().ConfigureAwait(false);
        }
    }
}


================================================
FILE: Database/Query/IFirebaseQuery.cs
================================================
namespace Firebase.Xamarin.Database.Query
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;

    using Firebase.Xamarin.Database.Streaming;

    /// <summary>
    /// The FirebaseQuery interface.
    /// </summary>
    public interface IFirebaseQuery
    {
        /// <summary>
        /// Retrieves items which exist on the location specified by this query instance.
        /// </summary>
        /// <typeparam name="T"> Type of the items. </typeparam>
        /// <returns> Collection of <see cref="FirebaseObject{T}"/>. </returns> 
        Task<IReadOnlyCollection<FirebaseObject<T>>> OnceAsync<T>();

        /// <summary>
        /// Returns current location as an observable which allows to real-time listening to events from the firebase server. 
        /// </summary>
        /// <typeparam name="T"> Type of the items. </typeparam>
        /// <returns> Cold observable of <see cref="FirebaseEvent{T}"/>. </returns>
        IObservable<FirebaseEvent<T>> AsObservable<T>(string elementRoot = "");

        /// <summary>
        /// Builds the actual url of this query.
        /// </summary>
        /// <returns> The <see cref="string"/>. </returns>
        Task<string> BuildUrlAsync();
    }
}


================================================
FILE: Database/Query/OrderQuery.cs
================================================
namespace Firebase.Xamarin.Database.Query
{
    using System;

    /// <summary>
    /// Represents a firebase ordering query, e.g. "?OrderBy=Foo".
    /// </summary>
    public class OrderQuery : ParameterQuery
    {
        private readonly Func<string> propertyNameFactory;

        /// <summary>
        /// Initializes a new instance of the <see cref="OrderQuery"/> class.
        /// </summary>
        /// <param name="parent"> The query parent. </param>
        /// <param name="propertyNameFactory"> The property name. </param>
        /// <param name="client"> The owning client. </param>
        public OrderQuery(ChildQuery parent, Func<string> propertyNameFactory, FirebaseClient client)
            : base(parent, () => "orderBy", client)
        {
            this.propertyNameFactory = propertyNameFactory;
        }

        /// <summary>
        /// The build url parameter.
        /// </summary>
        /// <param name="child"> The child. </param>
        /// <returns> The <see cref="string"/>. </returns>
        protected override string BuildUrlParameter(FirebaseQuery child)
        {
            return $"\"{this.propertyNameFactory()}\"";
        }
    }
}


================================================
FILE: Database/Query/ParameterQuery.cs
================================================
namespace Firebase.Xamarin.Database.Query
{
    using System;

    /// <summary>
    /// Represents a parameter in firebase query, e.g. "?data=foo".
    /// </summary>
    public abstract class ParameterQuery : FirebaseQuery
    {
        private readonly Func<string> parameterFactory;
        private readonly string separator;

        /// <summary>
        /// Initializes a new instance of the <see cref="ParameterQuery"/> class.
        /// </summary>
        /// <param name="parent"> The parent of this query. </param>
        /// <param name="parameterFactory"> The parameter. </param>
        /// <param name="client"> The owning client. </param>
        protected ParameterQuery(FirebaseQuery parent, Func<string> parameterFactory, FirebaseClient client)
            : base(parent, client)
        {
            this.parameterFactory = parameterFactory;
            this.separator = (this.Parent is ChildQuery) ? "?" : "&";
        }

        /// <summary>
        /// Build the url segment represented by this query. 
        /// </summary> 
        /// <param name="child"> The child. </param>
        /// <returns> The <see cref="string"/>. </returns>
        protected override string BuildUrlSegment(FirebaseQuery child)
        {
            return $"{this.separator}{this.parameterFactory()}={this.BuildUrlParameter(child)}";
        }

        /// <summary>
        /// The build url parameter.
        /// </summary>
        /// <param name="child"> The child. </param>
        /// <returns> The <see cref="string"/>. </returns>
        protected abstract string BuildUrlParameter(FirebaseQuery child);
    }
}


================================================
FILE: Database/Query/QueryExtensions.cs
================================================
namespace Firebase.Xamarin.Database.Query
{
    /// <summary>
    /// Query extensions providing linq like syntax for firebase server methods.
    /// </summary>
    public static class QueryExtensions
    {
        /// <summary>
        /// Adds an auth parameter to the query.
        /// </summary>
        /// <param name="node"> The child. </param>
        /// <param name="token"> The auth token. </param>
        /// <returns> The <see cref="AuthQuery"/>. </returns>
        public static AuthQuery WithAuth(this FirebaseQuery node, string token)
        {
            return node.WithAuth(() => token);
        }

        /// <summary>
        /// References a sub child of the existing node.
        /// </summary>
        /// <param name="node"> The child. </param>
        /// <param name="path"> The path of sub child. </param>
        /// <returns> The <see cref="ChildQuery"/>. </returns>
        public static ChildQuery Child(this ChildQuery node, string path)
        {
            return node.Child(() => path);
        }

        /// <summary>
        /// Order data by given <see cref="propertyName"/>. Note that this is used mainly for following filtering queries and due to firebase implementation
        /// the data may actually not be ordered.
        /// </summary>
        /// <param name="child"> The child. </param>
        /// <param name="propertyName"> The property name. </param>
        /// <returns> The <see cref="OrderQuery"/>. </returns>
        public static OrderQuery OrderBy(this ChildQuery child, string propertyName)
        {
            return child.OrderBy(() => propertyName);
        }

        /// <summary>
        /// Instructs firebase to send data greater or equal to the <see cref="value"/>. This must be preceded by an OrderBy query.
        /// </summary>
        /// <param name="child"> Current node. </param>
        /// <param name="value"> Value to start at. </param>
        /// <returns> The <see cref="FilterQuery"/>. </returns>
        public static FilterQuery StartAt(this ParameterQuery child, string value)
        {
            return child.StartAt(() => value);
        }

        /// <summary>
        /// Instructs firebase to send data lower or equal to the <see cref="value"/>. This must be preceded by an OrderBy query.
        /// </summary>
        /// <param name="child"> Current node. </param>
        /// <param name="value"> Value to start at. </param>
        /// <returns> The <see cref="FilterQuery"/>. </returns>
        public static FilterQuery EndAt(this ParameterQuery child, string value)
        {
            return child.EndAt(() => value);
        }

        /// <summary>
        /// Instructs firebase to send data equal to the <see cref="value"/>. This must be preceded by an OrderBy query.
        /// </summary>
        /// <param name="child"> Current node. </param>
        /// <param name="value"> Value to start at. </param>
        /// <returns> The <see cref="FilterQuery"/>. </returns>
        public static FilterQuery EqualTo(this ParameterQuery child, string value)
        {
            return child.EqualTo(() => value);
        }

        /// <summary>
        /// Instructs firebase to send data greater or equal to the <see cref="value"/>. This must be preceded by an OrderBy query.
        /// </summary>
        /// <param name="child"> Current node. </param>
        /// <param name="value"> Value to start at. </param>
        /// <returns> The <see cref="FilterQuery"/>. </returns>
        public static FilterQuery StartAt(this ParameterQuery child, double value)
        {
            return child.StartAt(() => value);
        }

        /// <summary>
        /// Instructs firebase to send data lower or equal to the <see cref="value"/>. This must be preceded by an OrderBy query.
        /// </summary>
        /// <param name="child"> Current node. </param>
        /// <param name="value"> Value to start at. </param>
        /// <returns> The <see cref="FilterQuery"/>. </returns>
        public static FilterQuery EndAt(this ParameterQuery child, double value)
        {
            return child.EndAt(() => value);
        }

        /// <summary>
        /// Instructs firebase to send data equal to the <see cref="value"/>. This must be preceded by an OrderBy query.
        /// </summary>
        /// <param name="child"> Current node. </param>
        /// <param name="value"> Value to start at. </param>
        /// <returns> The <see cref="FilterQuery"/>. </returns>
        public static FilterQuery EqualTo(this ParameterQuery child, double value)
        {
            return child.EqualTo(() => value);
        }

        /// <summary>
        /// Limits the result to first <see cref="count"/> items.
        /// </summary>
        /// <param name="child"> Current node. </param>
        /// <param name="count"> Number of elements. </param>
        /// <returns> The <see cref="FilterQuery"/>. </returns>
        public static FilterQuery LimitToFirst(this ParameterQuery child, int count)
        {
            return child.LimitToFirst(() => count);
        }

        /// <summary>
        /// Limits the result to last <see cref="count"/> items.
        /// </summary>
        /// <param name="child"> Current node. </param>
        /// <param name="count"> Number of elements. </param>
        /// <returns> The <see cref="FilterQuery"/>. </returns>
        public static FilterQuery LimitToLast(this ParameterQuery child, int count)
        {
            return child.LimitToLast(() => count);
        }
    }
}


================================================
FILE: Database/Query/QueryFactoryExtensions.cs
================================================
namespace Firebase.Xamarin.Database.Query
{
    using System;

    /// <summary>
    /// Query extensions providing linq like syntax for firebase server methods.
    /// </summary>
    public static class QueryFactoryExtensions
    {
        /// <summary>
        /// Adds an auth parameter to the query.
        /// </summary>
        /// <param name="node"> The child. </param>
        /// <param name="tokenFactory"> The auth token. </param>
        /// <returns> The <see cref="AuthQuery"/>. </returns>
        public static AuthQuery WithAuth(this FirebaseQuery node, Func<string> tokenFactory)
        {
            return new AuthQuery(node, tokenFactory, node.Client);
        }

        /// <summary>
        /// References a sub child of the existing node.
        /// </summary>
        /// <param name="node"> The child. </param>
        /// <param name="pathFactory"> The path of sub child. </param>
        /// <returns> The <see cref="ChildQuery"/>. </returns>
        public static ChildQuery Child(this ChildQuery node, Func<string> pathFactory)
        {
            return new ChildQuery(node, pathFactory, node.Client);
        }

        /// <summary>
        /// Order data by given <see cref="propertyNameFactory"/>. Note that this is used mainly for following filtering queries and due to firebase implementation
        /// the data may actually not be ordered.
        /// </summary>
        /// <param name="child"> The child. </param>
        /// <param name="propertyNameFactory"> The property name. </param>
        /// <returns> The <see cref="OrderQuery"/>. </returns>
        public static OrderQuery OrderBy(this ChildQuery child, Func<string> propertyNameFactory)
        {
            return new OrderQuery(child, propertyNameFactory, child.Client);
        }

        /// <summary>
        /// Order data by $key. Note that this is used mainly for following filtering queries and due to firebase implementation
        /// the data may actually not be ordered.
        /// </summary>
        /// <param name="child"> The child. </param>
        /// <returns> The <see cref="OrderQuery"/>. </returns>
        public static OrderQuery OrderByKey(this ChildQuery child)
        {
            return child.OrderBy("$key");
        }

        /// <summary>
        /// Order data by $value. Note that this is used mainly for following filtering queries and due to firebase implementation
        /// the data may actually not be ordered.
        /// </summary>
        /// <param name="child"> The child. </param>
        /// <returns> The <see cref="OrderQuery"/>. </returns>
        public static OrderQuery OrderByValue(this ChildQuery child)
        {
            return child.OrderBy("$value");
        }

        /// <summary>
        /// Order data by $priority. Note that this is used mainly for following filtering queries and due to firebase implementation
        /// the data may actually not be ordered.
        /// </summary>
        /// <param name="child"> The child. </param>
        /// <returns> The <see cref="OrderQuery"/>. </returns>
        public static OrderQuery OrderByPriority(this ChildQuery child)
        {
            return child.OrderBy("$priority");
        }

        /// <summary>
        /// Instructs firebase to send data greater or equal to the <see cref="valueFactory"/>. This must be preceded by an OrderBy query.
        /// </summary>
        /// <param name="child"> Current node. </param>
        /// <param name="valueFactory"> Value to start at. </param>
        /// <returns> The <see cref="FilterQuery"/>. </returns>
        public static FilterQuery StartAt(this ParameterQuery child, Func<string> valueFactory)
        {
            return new FilterQuery(child, () => "startAt", valueFactory, child.Client);
        }

        /// <summary>
        /// Instructs firebase to send data lower or equal to the <see cref="valueFactory"/>. This must be preceded by an OrderBy query.
        /// </summary>
        /// <param name="child"> Current node. </param>
        /// <param name="valueFactory"> Value to start at. </param>
        /// <returns> The <see cref="FilterQuery"/>. </returns>
        public static FilterQuery EndAt(this ParameterQuery child, Func<string> valueFactory)
        {
            return new FilterQuery(child, () => "endAt", valueFactory, child.Client);
        }

        /// <summary>
        /// Instructs firebase to send data equal to the <see cref="valueFactory"/>. This must be preceded by an OrderBy query.
        /// </summary>
        /// <param name="child"> Current node. </param>
        /// <param name="valueFactory"> Value to start at. </param>
        /// <returns> The <see cref="FilterQuery"/>. </returns>
        public static FilterQuery EqualTo(this ParameterQuery child, Func<string> valueFactory)
        {
            return new FilterQuery(child, () => "equalTo", valueFactory, child.Client);
        }

        /// <summary>
        /// Instructs firebase to send data greater or equal to the <see cref="valueFactory"/>. This must be preceded by an OrderBy query.
        /// </summary>
        /// <param name="child"> Current node. </param>
        /// <param name="valueFactory"> Value to start at. </param>
        /// <returns> The <see cref="FilterQuery"/>. </returns>
        public static FilterQuery StartAt(this ParameterQuery child, Func<double> valueFactory)
        {
            return new FilterQuery(child, () => "startAt", valueFactory, child.Client);
        }

        /// <summary>
        /// Instructs firebase to send data lower or equal to the <see cref="valueFactory"/>. This must be preceded by an OrderBy query.
        /// </summary>
        /// <param name="child"> Current node. </param>
        /// <param name="valueFactory"> Value to start at. </param>
        /// <returns> The <see cref="FilterQuery"/>. </returns>
        public static FilterQuery EndAt(this ParameterQuery child, Func<double> valueFactory)
        {
            return new FilterQuery(child, () => "endAt", valueFactory, child.Client);
        }

        /// <summary>
        /// Instructs firebase to send data equal to the <see cref="valueFactory"/>. This must be preceded by an OrderBy query.
        /// </summary>
        /// <param name="child"> Current node. </param>
        /// <param name="valueFactory"> Value to start at. </param>
        /// <returns> The <see cref="FilterQuery"/>. </returns>
        public static FilterQuery EqualTo(this ParameterQuery child, Func<double> valueFactory)
        {
            return new FilterQuery(child, () => "equalTo", valueFactory, child.Client);
        }

        /// <summary>
        /// Limits the result to first <see cref="countFactory"/> items.
        /// </summary>
        /// <param name="child"> Current node. </param>
        /// <param name="countFactory"> Number of elements. </param>
        /// <returns> The <see cref="FilterQuery"/>. </returns>
        public static FilterQuery LimitToFirst(this ParameterQuery child, Func<int> countFactory)
        {
            return new FilterQuery(child, () => "limitToFirst", () => countFactory(), child.Client);
        }

        /// <summary>
        /// Limits the result to last <see cref="countFactory"/> items.
        /// </summary>
        /// <param name="child"> Current node. </param>
        /// <param name="countFactory"> Number of elements. </param>
        /// <returns> The <see cref="FilterQuery"/>. </returns>
        public static FilterQuery LimitToLast(this ParameterQuery child, Func<int> countFactory)
        {
            return new FilterQuery(child, () => "limitToLast", () => countFactory(), child.Client);
        }
    }
}


================================================
FILE: Database/Streaming/FirebaseCache.cs
================================================
namespace Firebase.Xamarin.Database.Streaming
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;

    using Firebase.Xamarin.Database.Http;

    using Newtonsoft.Json;

    /// <summary>
    /// The firebase cache.
    /// </summary>
    /// <typeparam name="T"> Type of top-level entities in the cache. </typeparam>
    public class FirebaseCache<T> : IEnumerable<FirebaseObject<T>>
    {
        private readonly IDictionary<string, T> dictionary;

        /// <summary>
        /// Initializes a new instance of the <see cref="FirebaseCache{T}"/> class.
        /// </summary>
        public FirebaseCache() 
            : this(new Dictionary<string, T>())
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="FirebaseCache{T}"/> class and populates it with existing data.
        /// </summary>
        /// <param name="existingItems"> The existing items. </param>
        public FirebaseCache(IDictionary<string, T> existingItems)
        {
            this.dictionary = existingItems;
        }

        /// <summary>
        /// The push data.
        /// </summary>
        /// <param name="path"> The path of incoming data, separated by slash. </param>  
        /// <param name="data"> The data in json format as returned by firebase. </param>  
        /// <returns> Collection of top-level entities which were affected by the push. </returns>
        public IEnumerable<FirebaseObject<T>> PushData(string path, string data) 
        {
            object obj = this.dictionary;
            Action<object> primitiveObjSetter = null;
            Action objDeleter = null;

            var pathElements = path.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries);

            // first find where we should insert the data to
            foreach (var element in pathElements)
            {
                if (obj is IDictionary)
                {
                    // if it's a dictionary, then it's just a matter of inserting into it / accessing existing object by key
                    var dictionary = obj as IDictionary;
                    var valueType = obj.GetType().GenericTypeArguments[1];

                    primitiveObjSetter = (d) => dictionary[element] = d;
                    objDeleter = () => dictionary.Remove(element);

                    if (dictionary.Contains(element))
                    {
                        obj = dictionary[element];
                    }
                    else
                    {
                        if (valueType == typeof(string))
                        {
                            dictionary[element] = string.Empty;
                            obj = dictionary[element];
                        }
                        else
                        {
                            dictionary[element] = Activator.CreateInstance(valueType);
                            obj = dictionary[element];
                        }
                    }
                }
                else
                {
                    // if it's not a dictionary, try to find the property of current object with the matching name
                    var objParent = obj;
                    var property = objParent
                        .GetType()
                        .GetRuntimeProperties()
                        .First(p => p.Name.Equals(element, StringComparison.OrdinalIgnoreCase) || element == p.GetCustomAttribute<JsonPropertyAttribute>()?.PropertyName);

                    objDeleter = () => property.SetValue(objParent, null);
                    primitiveObjSetter = (d) => property.SetValue(objParent, d);
                    obj = property.GetValue(obj);
                }
            }

            // if data is null (=empty string) delete it
            if (string.IsNullOrWhiteSpace(data))
            {
                var key = pathElements[0];
                var target = this.dictionary[key];

                objDeleter();

                yield return new FirebaseObject<T>(key, target);
                yield break;
            }

            // now insert the data
            if (obj is IDictionary)
            {
                // insert data into dictionary and return it as a collection of FirebaseObject
                var dictionary = obj as IDictionary;
                var valueType = obj.GetType().GenericTypeArguments[1];
                var objectCollection = data.GetObjectCollection(valueType);

                foreach (var item in objectCollection)
                {
                    dictionary[item.Key] = item.Object;
                    yield return new FirebaseObject<T>(item.Key, (T)item.Object);
                }
            }
            else
            {
                // set the data on a property of the given object
                var valueType = obj.GetType();
                var targetObject = JsonConvert.DeserializeObject(data, valueType);

                if ((valueType.GetTypeInfo().IsPrimitive || valueType == typeof(string)) && primitiveObjSetter != null)
                {
                    // handle primitive (value) types separately
                    primitiveObjSetter(targetObject);
                }
                else
                {
                    JsonConvert.PopulateObject(data, obj);
                }

                this.dictionary[pathElements[0]] = this.dictionary[pathElements[0]];
                yield return new FirebaseObject<T>(pathElements[0], this.dictionary[pathElements[0]]);
            }
        }

        #region IEnumerable

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        public IEnumerator<FirebaseObject<T>> GetEnumerator()
        {
            return this.dictionary.Select(p => new FirebaseObject<T>(p.Key, p.Value)).GetEnumerator();
        }

        #endregion
    }
}


================================================
FILE: Database/Streaming/FirebaseEvent.cs
================================================
namespace Firebase.Xamarin.Database.Streaming
{
    /// <summary>
    /// Firebase event which hold <see cref="EventType"/> and the object affected by the event.
    /// </summary>
    /// <typeparam name="T"> Type of object affected by the event. </typeparam>
    public class FirebaseEvent<T> : FirebaseObject<T>
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="FirebaseEvent{T}"/> class.
        /// </summary>
        /// <param name="key"> The key of the object. </param>
        /// <param name="obj"> The object. </param>
        /// <param name="eventType"> The event type. </param>
        public FirebaseEvent(string key, T obj, FirebaseEventType eventType)
            : base(key, obj)
        {
            this.EventType = eventType;
        }

        /// <summary>
        /// Gets the event type.
        /// </summary>
        public FirebaseEventType EventType
        {
            get;
        }
    }
}


================================================
FILE: Database/Streaming/FirebaseEventType.cs
================================================
namespace Firebase.Xamarin.Database.Streaming
{
    /// <summary>
    /// The type of event. 
    /// </summary>
    public enum FirebaseEventType
    {
        /// <summary>
        /// Item was inserted or updated.
        /// </summary>
        InsertOrUpdate,

        /// <summary>
        /// Item was deleted.
        /// </summary>
        Delete
    }
}


================================================
FILE: Database/Streaming/FirebaseServerEventType.cs
================================================
namespace Firebase.Xamarin.Database.Streaming
{
    internal enum FirebaseServerEventType
    {
        Put,

        Patch,

        KeepAlive,

        Cancel,

        AuthRevoked
    }
}


================================================
FILE: Database/Streaming/FirebaseSubscription.cs
================================================
namespace Firebase.Xamarin.Database.Streaming
{
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Threading;
    using System.Threading.Tasks;

    using Firebase.Xamarin.Database.Query;

    using Newtonsoft.Json.Linq;

    /// <summary>
    /// The firebase subscription.
    /// </summary>
    /// <typeparam name="T"> Type of object to be streaming back to the called. </typeparam>
    internal class FirebaseSubscription<T> : IDisposable
    {
        private readonly CancellationTokenSource cancel;
        private readonly HttpClient httpClient;
        private readonly IObserver<FirebaseEvent<T>> observer;
        private readonly IFirebaseQuery query;
        private readonly FirebaseCache<T> cache;
        private readonly string elementRoot;

        /// <summary>
        /// Initializes a new instance of the <see cref="FirebaseSubscription{T}"/> class.
        /// </summary>
        /// <param name="observer"> The observer.  </param>
        /// <param name="query"> The query.  </param>
        /// <param name="cache"> The cache. </param>
        public FirebaseSubscription(IObserver<FirebaseEvent<T>> observer, IFirebaseQuery query, string elementRoot, FirebaseCache<T> cache)
        {
            this.observer = observer;
            this.query = query;
            this.elementRoot = elementRoot;
            this.cancel = new CancellationTokenSource();
            this.httpClient = new HttpClient();
            this.cache = cache;

            var handler = new HttpClientHandler
            {
                AllowAutoRedirect = true,
                MaxAutomaticRedirections = 10,
            };

            this.httpClient = new HttpClient(handler, true)
            {
                Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite),
            };

            this.httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/event-stream"));
        }

        public void Dispose()
        {
            this.httpClient.Dispose();
            this.cancel.Cancel();
        }

        public IDisposable Run()
        {
            Task.Factory.StartNew(this.ReceiveThread);

            return this;
        }

        private async void ReceiveThread()
        {
            while (true)
            {
                try
                {
                    this.cancel.Token.ThrowIfCancellationRequested();

                    // initialize network connection
                    var serverEvent = FirebaseServerEventType.KeepAlive;
                    var request = new HttpRequestMessage(HttpMethod.Get, await this.query.BuildUrlAsync().ConfigureAwait(false));
                    var response = await this.httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, this.cancel.Token).ConfigureAwait(false);

                    response.EnsureSuccessStatusCode();

                    using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
                    using (var reader = new StreamReader(stream))
                    {
                        while (true)
                        {
                            var line = reader.ReadLine();

                            this.cancel.Token.ThrowIfCancellationRequested();

                            if (string.IsNullOrWhiteSpace(line))
                            {
                                await Task.Delay(2000).ConfigureAwait(false);
                                continue;
                            }

                            var tuple = line.Split(new[] { ':' }, 2, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToArray();

                            switch (tuple[0].ToLower())
                            {
                                case "event":
                                    serverEvent = this.ParseServerEvent(serverEvent, tuple[1]);
                                    break;
                                case "data":
                                    this.ProcessServerData(serverEvent, tuple[1]);
                                    break;
                            }

                            if (serverEvent == FirebaseServerEventType.AuthRevoked)
                            {
                                // auth token no longer valid, reconnect
                                break;
                            }
                        }
                    }
                }
                catch (OperationCanceledException)
                {
                    break;
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("************************************************************");
                    Debug.WriteLine(ex.ToString());
                    Debug.WriteLine("************************************************************");
                    await Task.Delay(2000).ConfigureAwait(false);
                }
            }
        }

        private FirebaseServerEventType ParseServerEvent(FirebaseServerEventType serverEvent, string eventName)
        {
            switch (eventName)
            {
                case "put":
                    serverEvent = FirebaseServerEventType.Put;
                    break;
                case "patch":
                    serverEvent = FirebaseServerEventType.Patch;
                    break;
                case "keep-alive":
                    serverEvent = FirebaseServerEventType.KeepAlive;
                    break;
                case "cancel":
                    serverEvent = FirebaseServerEventType.Cancel;
                    break;
                case "auth_revoked":
                    serverEvent = FirebaseServerEventType.AuthRevoked;
                    break;
            }

            return serverEvent;
        }

        private void ProcessServerData(FirebaseServerEventType serverEvent, string serverData)
        {
            switch (serverEvent)
            {
                case FirebaseServerEventType.Put:
                case FirebaseServerEventType.Patch:
                    var result = JObject.Parse(serverData);
                    var path = result["path"].ToString();
                    var data = result["data"].ToString();
                    var eventType = string.IsNullOrWhiteSpace(data) ? FirebaseEventType.Delete : FirebaseEventType.InsertOrUpdate;

                    var items = this.cache.PushData(this.elementRoot + path, data);

                    foreach (var i in items.ToList())
                    {
                        this.observer.OnNext(new FirebaseEvent<T>(i.Key, i.Object, eventType));
                    }

                    break;
                case FirebaseServerEventType.KeepAlive:
                    break;
                case FirebaseServerEventType.Cancel:
                    this.observer.OnError(new Exception("cancel"));
                    this.Dispose();
                    throw new OperationCanceledException();
                case FirebaseServerEventType.AuthRevoked:
                    this.observer.OnError(new Exception("auth"));
                    this.Dispose();
                    throw new OperationCanceledException();
            }
        }
    }
}


================================================
FILE: Firebase.Xamarin.csproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{4ED07DF1-95A7-4780-BC6A-BEF0BD4FF4C3}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>Firebase.Xamarin</RootNamespace>
    <AssemblyName>Firebase.Xamarin</AssemblyName>
    <DefaultLanguage>en-US</DefaultLanguage>
    <FileAlignment>512</FileAlignment>
    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
    <TargetFrameworkProfile>Profile111</TargetFrameworkProfile>
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="Auth\FirebaseAuth.cs" />
    <Compile Include="Auth\FirebaseAuthLink.cs" />
    <Compile Include="Auth\FirebaseAuthProvider.cs" />
    <Compile Include="Auth\FirebaseAuthType.cs" />
    <Compile Include="Auth\FirebaseConfig.cs" />
    <Compile Include="Auth\IFirebaseAuthProvider.cs" />
    <Compile Include="Auth\User.cs" />
    <Compile Include="Database\FirebaseClient.cs" />
    <Compile Include="Database\FirebaseKeyGenerator.cs" />
    <Compile Include="Database\FirebaseObject.cs" />
    <Compile Include="Database\GlobalSuppressions.cs" />
    <Compile Include="Database\ObservableExtensions.cs" />
    <Compile Include="Database\Http\HttpClientExtensions.cs" />
    <Compile Include="Database\Http\PostResult.cs" />
    <Compile Include="Database\Offline\ExceptionEventArgs.cs" />
    <Compile Include="Database\Offline\OfflineCacheAdapter.cs" />
    <Compile Include="Database\Offline\OfflineEntry.cs" />
    <Compile Include="Database\Offline\RealtimeDatabase.cs" />
    <Compile Include="Database\Offline\SyncOptions.cs" />
    <Compile Include="Database\Properties\AssemblyInfo.cs" />
    <Compile Include="Database\Query\AuthQuery.cs" />
    <Compile Include="Database\Query\ChildQuery.cs" />
    <Compile Include="Database\Query\FilterQuery.cs" />
    <Compile Include="Database\Query\FirebaseQuery.cs" />
    <Compile Include="Database\Query\IFirebaseQuery.cs" />
    <Compile Include="Database\Query\OrderQuery.cs" />
    <Compile Include="Database\Query\ParameterQuery.cs" />
    <Compile Include="Database\Query\QueryExtensions.cs" />
    <Compile Include="Database\Query\QueryFactoryExtensions.cs" />
    <Compile Include="Database\Streaming\FirebaseCache.cs" />
    <Compile Include="Database\Streaming\FirebaseEvent.cs" />
    <Compile Include="Database\Streaming\FirebaseEventType.cs" />
    <Compile Include="Database\Streaming\FirebaseServerEventType.cs" />
    <Compile Include="Database\Streaming\FirebaseSubscription.cs" />
    <Compile Include="Token\StreamToken.cs" />
    <Compile Include="Token\TokenGenerator.cs" />
    <Compile Include="Token\TokenOptions.cs" />
    <Compile Include="Auth\FirebaseAuthException.cs" />
    <Compile Include="Notification\PushNotification.cs" />
  </ItemGroup>
  <ItemGroup>
    <Reference Include="System.Reactive.Core, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>packages\Rx-Core.2.2.5\lib\portable-net45+winrt45+wp8+wpa81\System.Reactive.Core.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="System.Reactive.Interfaces, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>packages\Rx-Interfaces.2.2.5\lib\portable-net45+winrt45+wp8+wpa81\System.Reactive.Interfaces.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="System.Reactive.Linq, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>packages\Rx-Linq.2.2.5\lib\portable-net45+winrt45+wp8+wpa81\System.Reactive.Linq.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="System.Reactive.PlatformServices, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>packages\Rx-PlatformServices.2.2.5\lib\portable-net45+winrt45+wp8+wpa81\System.Reactive.PlatformServices.dll</HintPath>
      <Private>True</Private>
    </Reference>
    <Reference Include="crypto">
      <HintPath>packages\Portable.BouncyCastle.1.8.0\lib\portable-net45+win8+wpa81+MonoTouch10+MonoAndroid10+xamarinmac20+xamarinios10\crypto.dll</HintPath>
    </Reference>
    <Reference Include="JWT">
      <HintPath>packages\Portable.JWT.1.0.5\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\JWT.dll</HintPath>
    </Reference>
    <Reference Include="Newtonsoft.Json">
      <HintPath>packages\Newtonsoft.Json.9.0.1\lib\portable-net45+wp80+win8+wpa81\Newtonsoft.Json.dll</HintPath>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <None Include="packages.config" />
  </ItemGroup>
  <ItemGroup>
    <Folder Include="Token\" />
    <Folder Include="Notification\" />
  </ItemGroup>
  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>


================================================
FILE: Firebase.Xamarin.sln
================================================

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25123.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Firebase.Xamarin", "Firebase.Xamarin.csproj", "{4ED07DF1-95A7-4780-BC6A-BEF0BD4FF4C3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NuGet.Packager", "..\NuGet.Packager\NuGet.Packager.csproj", "{0451BAEF-DF2E-4B98-8644-94EE9415E389}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Release|Any CPU = Release|Any CPU
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{4ED07DF1-95A7-4780-BC6A-BEF0BD4FF4C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{4ED07DF1-95A7-4780-BC6A-BEF0BD4FF4C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{4ED07DF1-95A7-4780-BC6A-BEF0BD4FF4C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{4ED07DF1-95A7-4780-BC6A-BEF0BD4FF4C3}.Release|Any CPU.Build.0 = Release|Any CPU
		{0451BAEF-DF2E-4B98-8644-94EE9415E389}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{0451BAEF-DF2E-4B98-8644-94EE9415E389}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{0451BAEF-DF2E-4B98-8644-94EE9415E389}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{0451BAEF-DF2E-4B98-8644-94EE9415E389}.Release|Any CPU.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2016 ricardo

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: Notification/PushNotification.cs
================================================
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Firebase.Xamarin.Auth;

namespace Firebase.Xamarin.Notification
{
  public class PushNotification
  {
    private const string NotificationUrl = "https://fcm.googleapis.com/fcm/send";

    private readonly FirebaseConfig authConfig;

    public PushNotification(FirebaseConfig authConfig)
    {
      this.authConfig = authConfig;
    }

    public async Task Send(string to, string title, string message)
    {
      using (HttpClient client = new HttpClient())
      {
        var postContent = $"{{\"to\":\"{to}\",\"notification\":{{ \"title\":\"{title}\",\"text\":\"{message}\" }}}}";

        client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("key", $"={this.authConfig.ApiKeyForPushNotification}");
        var response = await client.PostAsync(NotificationUrl, new StringContent(postContent, Encoding.UTF8, "application/json")).ConfigureAwait(false);

        response.EnsureSuccessStatusCode();
      }
    }
  }
}


================================================
FILE: Properties/AssemblyInfo.cs
================================================
using System.Resources;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Firebase.Xamarin")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Firebase.Xamarin")]
[assembly: AssemblyCopyright("Copyright ©  2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]


================================================
FILE: README.md
================================================
# Firebase.Xamarin
Light weight wrapper for Firebase Realtime Database REST API.
## Installation
```csharp
// Install release version
Install-Package Firebase.Xamarin

```

## Supported frameworks
* .NET 4.5+
* ASP.Net Core 1.0
* Xamarin Android
* Xamarin iOS 
* Xamarin iOS Classic
* Windows 8

## Usage

Depending on your [database rules](https://firebase.google.com/docs/database/security/) you may need to first Authenticate with your Auth Provider. Instructions for Authentication are towards the bottom.

### Querying

```csharp
var firebase = new FirebaseClient("https://yourdatabase.firebaseio.com/");
var items = await firebase
  .Child("yourentity")
  //.WithAuth("<Authentication Token>") // <-- Add Auth token if required. Auth instructions further down in readme.
  .OrderByKey()
  .LimitToFirst(2)
  .OnceAsync<YourObject>();
  
foreach (var item in items)
{
  Console.WriteLine($"{item.Key} name is {item.Object.Name}");
}
```

### Saving data

```csharp
var firebase = new FirebaseClient("https://yourdatabase.firebaseio.com/");

// add new item to list of data 
var item = await firebase
  .Child("yourentity")
  //.WithAuth("<Authentication Token>") // <-- Add Auth token if required. Auth instructions further down in readme.
  .PostAsync(new YourObject());
  
// note that there is another overload for the PostAsync method which delegates the new key generation to the client
  
Console.WriteLine($"Key for the new item: {item.Key}");  

// add new item directly to the specified location (this will overwrite whatever data already exists at that location)
var item = await firebase
  .Child("yourentity")
  .Child("Ricardo")
  //.WithAuth("<Authentication Token>") // <-- Add Auth token if required. Auth instructions further down in readme.
  .PutAsync(new YourObject());

```

### Realtime streaming

```csharp
var firebase = new FirebaseClient("https://dinosaur-facts.firebaseio.com/");
var observable = firebase
  .Child("dinosaurs")
  .AsObservable<Dinosaur>()
  .Subscribe(d => Console.WriteLine(d.Key));
  
```

```AsObservable<T>``` methods returns an ```IObservable<T>``` which you can take advantage of using [Reactive Extensions](https://github.com/Reactive-Extensions/Rx.NET)


## Authentication

### firebase.google.com Auth

You will need a firebase.google.com API Key for Authentication. The easiset way to find this is to click on 'Add Firebase to your web app' in the Overview section of your firebase.google.com console. The site will generate a JavaScript snippet that contains the ```apiKey``` variable.
```csharp
// Email/Password Auth
var authProvider = new FirebaseAuthProvider(new FirebaseConfig("<google.firebase.com API Key>"));

var auth = await authProvider.CreateUserWithEmailAndPasswordAsync("email@email.com", "password");

// The auth Object will contain auth.User and the Authentication Token from the request
System.Diagnostics.Debug.WriteLine(auth.FirebaseToken);


// Facebook Auth
var authProvider = new FirebaseAuthProvider(new FirebaseConfig("<google.firebase.com API Key>"));
var facebookAccessToken = "<login with facebook and get oauth access token>";

var auth = await authProvider.SignInWithOAuthAsync(FirebaseAuthType.Facebook, facebookAccessToken);

// Using the Auth token to make requests.. (see more on requests below)
var firebase = new FirebaseClient("https://dinosaur-facts.firebaseio.com/");
var dinos = await firebase
  .Child("dinosaurs")
  .WithAuth(auth.FirebaseToken) // <-- Note the use of the Firebase Auth Token
  .OnceAsync<Dinosaur>();

foreach (var dino in dinos)
{
  System.Diagnostics.Debug.WriteLine($"{dino.Key} is {dino.Object.Height}m high.");
}
```


### Custom Auth

#### Generating Tokens

To generate tokens, you'll need your Firebase Secret which you can find by entering your Firebase
URL into a browser and clicking the "Secrets" tab on the left-hand navigation menu.

Once you've downloaded the library and grabbed your Firebase Secret, you can generate a token with
this snippet of .Net code:

```
var tokenGenerator = new Firebase.TokenGenerator("<YOUR_FIREBASE_SECRET>");
var authPayload = new Dictionary<string, object>()
{
  { "uid", "1" },
  { "some", "arbitrary" },
  { "data", "here" }
};
string token = tokenGenerator.CreateToken(authPayload);
```

The payload object passed into `CreateToken()` is then available for use within your
security rules via the [`auth` variable](https://www.firebase.com/docs/security/api/rule/auth.html).
This is how you pass trusted authentication details (e.g. the client's user ID) to your
Firebase rules. The payload can contain any data of your choosing, however it
must contain a "uid" key, which must be a string of less than 256 characters. The
generated token must be less than 1024 characters in total.


#### Token Options

A second `options` argument can be passed to `CreateToken()` to modify how Firebase treats the
token. Available options are:

* **expires** (DateTime) - A timestamp denoting the time after which this token should no longer
be valid.

* **notBefore** (DateTime) - A timestamp denoting the time before which this token should be
rejected by the server.

* **admin** (bool) - Set to `true` if you want to disable all security rules for this client. This
will provide the client with read and write access to your entire Firebase.

* **debug** (bool) - Set to `true` to enable debug output from your security rules. You should
generally *not* leave this set to `true` in production (as it slows down the rules implementation
and gives your users visibility into your rules), but it can be helpful for debugging.

Here is an example of how to use the second `options` argument:

```
var tokenGenerator = new Firebase.TokenGenerator("<YOUR_FIREBASE_SECRET>");
var authPayload = new Dictionary<string, object>()
{
  { "uid", "1" },
  { "some", "arbitrary" },
  { "data", "here" }
};
string token = tokenGenerator.CreateToken(authPayload, new Firebase.TokenOptions(admin: true));
  
```
## Thanks
Special thanks to [bezysoftware](https://github.com/bezysoftware) for the original [firebase-database-dotnet] (https://github.com/step-up-labs/firebase-database-dotnet) and [firebase-authentication-dotnet] (https://github.com/step-up-labs/firebase-authentication-dotnet) code that is the core for this Xamarin adaptation. Also thanks to [mikelehen](https://github.com/mikelehen) for the original [Firebase Token Generator - .NET] (https://github.com/firebase/firebase-token-generator-dotNet)


================================================
FILE: Token/StreamToken.cs
================================================
namespace Firebase.Xamarin.Token
{
	using System;
	using System.Reactive.Linq;
	using Firebase.Xamarin.Database.Streaming;

	public class StreamToken<T> : IDisposable
	{
		private IDisposable _observableDisposable;
		private IObservable<FirebaseEvent<T>> _observable;

		public StreamToken(IObservable<FirebaseEvent<T>> observable)
		{
			_observable = observable;
		}

		public StreamToken<T> Where(Func<FirebaseEvent<T>, bool> predicate)
		{
			_observable = _observable.Where(predicate);
			return this;
		}

		public StreamToken<T> Throttle(TimeSpan timeSpan)
		{
			_observable = _observable.Throttle(timeSpan);
			return this;
		}

		public void Subscribe(Action<FirebaseEvent<T>> onDataAdded)
			=> _observableDisposable = _observable.Subscribe(d => onDataAdded(d));

		public void Dispose()
		{
			_observableDisposable?.Dispose();
		}
	}
}

================================================
FILE: Token/TokenGenerator.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;


namespace Firebase.Xamarin.Token
{
	public class TokenGenerator
	{
		private static int TOKEN_VERSION = 0;
		private string _firebaseSecret;

		/// <summary>
		/// Constructor.
		/// </summary>
		/// <param name="firebaseSecret">The Firebase Secret for your firebase (can be found by entering your Firebase URL into a web browser, and clicking the "Auth" pane).</param>
		public TokenGenerator(string firebaseSecret)
		{
			_firebaseSecret = firebaseSecret;
		}

		/// <summary>
		/// Creates an authentication token containing arbitrary auth data.
		/// </summary>
		/// <param name="data">Arbitrary data that will be passed to the Firebase Rules API, once a client authenticates.  Must be able to be serialized to JSON with <see cref="System.Web.Script.Serialization.JavaScriptSerializer"/>.</param>
		/// <returns>The auth token.</returns>
		public string CreateToken(Dictionary<string, object> data)
		{
			return CreateToken(data, new TokenOptions());
		}

		/// <summary>
		/// Creates an authentication token containing arbitrary auth data and the specified options.
		/// </summary>
		/// <param name="data">Arbitrary data that will be passed to the Firebase Rules API, once a client authenticates.  Must be able to be serialized to JSON with <see cref="System.Web.Script.Serialization.JavaScriptSerializer"/>.</param>
		/// <param name="options">A set of custom options for the token.</param>
		/// <returns>The auth token.</returns>
		public string CreateToken(Dictionary<string, object> data, TokenOptions options)
		{
			var dataEmpty = (data == null || data.Count == 0);
			if (dataEmpty && (options == null || (!options.admin && !options.debug)))
			{
				throw new Exception("data is empty and no options are set.  This token will have no effect on Firebase.");
			}

			var claims = new Dictionary<string, object>();
			claims["v"] = TOKEN_VERSION;
			claims["iat"] = secondsSinceEpoch(DateTime.Now);

			var isAdminToken = (options != null && options.admin);
			validateToken(data, isAdminToken);

			if (!dataEmpty)
			{
				claims["d"] = data;
			}

			// Handle options.
			if (options != null)
			{
				if (options.expires.HasValue)
					claims["exp"] = secondsSinceEpoch(options.expires.Value);
				if (options.notBefore.HasValue)
					claims["nbf"] = secondsSinceEpoch(options.notBefore.Value);
				if (options.admin)
					claims["admin"] = true;
				if (options.debug)
					claims["debug"] = true;
			}

			var token = computeToken(claims);
			if (token.Length > 1024)
			{
				throw new Exception("Generated token is too long. The token cannot be longer than 1024 bytes.");
			}
			return token;
		}

		private string computeToken(Dictionary<string, object> claims)
		{
			return JWT.JsonWebToken.Encode(claims, this._firebaseSecret, JWT.JwtHashAlgorithm.HS256);
		}

		private static long secondsSinceEpoch(DateTime dt)
		{
			TimeSpan t = dt.ToUniversalTime() - new DateTime(1970, 1, 1);
			return (long)t.TotalSeconds;
		}

		private static void validateToken(Dictionary<string, object> data, Boolean isAdminToken)
		{
			var containsUid = (data != null && data.ContainsKey("uid"));
			if ((!containsUid && !isAdminToken) || (containsUid && !(data["uid"] is string)))
			{
				throw new Exception("Data payload must contain a \"uid\" key that must not be a string.");
			}
			else if (containsUid && data["uid"].ToString().Length > 256)
			{
				throw new Exception("Data payload must contain a \"uid\" key that must not be longer than 256 characters.");
			}
		}
	}
}



================================================
FILE: Token/TokenOptions.cs
================================================
using System;

namespace Firebase.Xamarin.Token
{
	public class TokenOptions
	{
		public DateTime? expires { get; private set; }
		public DateTime? notBefore { get; private set; }
		public bool admin { get; private set; }
		public bool debug { get; private set; }

		/// <summary>
		/// Constructor.  All options are optional.
		/// </summary>
		/// <param name="notBefore">The date/time before which the token should not be considered valid. (default is now)</param>
		/// <param name="expires">The date/time at which the token should no longer be considered valid. (default is 24 hours from now)</param>
		/// <param name="admin">Set to true to bypass all security rules. (you can use this for trusted server code)</param>
		/// <param name="debug">Set to true to enable debug mode. (so you can see the results of Rules API operations)</param>
		public TokenOptions(DateTime? notBefore = null, DateTime? expires = null, bool admin = false, bool debug = false)
		{
			this.notBefore = notBefore;
			this.expires = expires;
			this.admin = admin;
			this.debug = debug;
		}
	}
}



================================================
FILE: TokenGenerator.config
================================================
<?xml version="1.0" encoding="utf-8"?>
<configuration>
</configuration>


================================================
FILE: packages.config
================================================
<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Newtonsoft.Json" version="9.0.1" targetFramework="portable-net45+win+wpa81+MonoTouch10+MonoAndroid10+xamarinmac20+xamarintvos10+xamarinwatchos10+xamarinios10" />
  <package id="Portable.BouncyCastle" version="1.8.0" targetFramework="portable-net45+win+wpa81+MonoTouch10+MonoAndroid10+xamarinmac20+xamarintvos10+xamarinwatchos10+xamarinios10" />
  <package id="Portable.JWT" version="1.0.5" targetFramework="portable-net45+win+wpa81+MonoTouch10+MonoAndroid10+xamarinmac20+xamarintvos10+xamarinwatchos10+xamarinios10" />
  <package id="Rx-Core" version="2.2.5" targetFramework="portable45-net45+win8+wpa81" />
  <package id="Rx-Interfaces" version="2.2.5" targetFramework="portable45-net45+win8+wpa81" />
  <package id="Rx-Linq" version="2.2.5" targetFramework="portable45-net45+win8+wpa81" />
  <package id="Rx-Main" version="2.2.5" targetFramework="portable45-net45+win8+wpa81" />
  <package id="Rx-PlatformServices" version="2.2.5" targetFramework="portable45-net45+win8+wpa81" />
</packages>
Download .txt
gitextract_p1_b5ys5/

├── .gitignore
├── Auth/
│   ├── FirebaseAuth.cs
│   ├── FirebaseAuthException.cs
│   ├── FirebaseAuthLink.cs
│   ├── FirebaseAuthProvider.cs
│   ├── FirebaseAuthType.cs
│   ├── FirebaseConfig.cs
│   ├── IFirebaseAuthProvider.cs
│   └── User.cs
├── Database/
│   ├── FirebaseClient.cs
│   ├── FirebaseKeyGenerator.cs
│   ├── FirebaseObject.cs
│   ├── GlobalSuppressions.cs
│   ├── Http/
│   │   ├── HttpClientExtensions.cs
│   │   └── PostResult.cs
│   ├── ObservableExtensions.cs
│   ├── Offline/
│   │   ├── ExceptionEventArgs.cs
│   │   ├── OfflineCacheAdapter.cs
│   │   ├── OfflineEntry.cs
│   │   ├── RealtimeDatabase.cs
│   │   └── SyncOptions.cs
│   ├── Properties/
│   │   └── AssemblyInfo.cs
│   ├── Query/
│   │   ├── AuthQuery.cs
│   │   ├── ChildQuery.cs
│   │   ├── FilterQuery.cs
│   │   ├── FirebaseQuery.cs
│   │   ├── IFirebaseQuery.cs
│   │   ├── OrderQuery.cs
│   │   ├── ParameterQuery.cs
│   │   ├── QueryExtensions.cs
│   │   └── QueryFactoryExtensions.cs
│   └── Streaming/
│       ├── FirebaseCache.cs
│       ├── FirebaseEvent.cs
│       ├── FirebaseEventType.cs
│       ├── FirebaseServerEventType.cs
│       └── FirebaseSubscription.cs
├── Firebase.Xamarin.csproj
├── Firebase.Xamarin.sln
├── LICENSE
├── Notification/
│   └── PushNotification.cs
├── Properties/
│   └── AssemblyInfo.cs
├── README.md
├── Token/
│   ├── StreamToken.cs
│   ├── TokenGenerator.cs
│   └── TokenOptions.cs
├── TokenGenerator.config
└── packages.config
Download .txt
SYMBOL INDEX (202 symbols across 37 files)

FILE: Auth/FirebaseAuth.cs
  class FirebaseAuth (line 8) | public class FirebaseAuth

FILE: Auth/FirebaseAuthException.cs
  class FirebaseIncorrectPasswordException (line 9) | public class FirebaseIncorrectPasswordException : Exception
    method FirebaseIncorrectPasswordException (line 14) | public FirebaseIncorrectPasswordException() : base()
    method FirebaseIncorrectPasswordException (line 22) | public FirebaseIncorrectPasswordException(String message) : base(message)
    method FirebaseIncorrectPasswordException (line 31) | public FirebaseIncorrectPasswordException(String message, Exception in...
  class FirebaseInvalidEmailException (line 36) | public class FirebaseInvalidEmailException : Exception
    method FirebaseInvalidEmailException (line 42) | public FirebaseInvalidEmailException() : base()
    method FirebaseInvalidEmailException (line 51) | public FirebaseInvalidEmailException(String message) : base(message)
    method FirebaseInvalidEmailException (line 61) | public FirebaseInvalidEmailException(String message, Exception innerEx...
  class FirebaseUsedEmailException (line 69) | public class FirebaseUsedEmailException : Exception
    method FirebaseUsedEmailException (line 75) | public FirebaseUsedEmailException() : base()
    method FirebaseUsedEmailException (line 84) | public FirebaseUsedEmailException(String message) : base(message)
    method FirebaseUsedEmailException (line 94) | public FirebaseUsedEmailException(String message, Exception innerExcep...
  class FirebaseWeakPasswordException (line 99) | public class FirebaseWeakPasswordException : Exception
    method FirebaseWeakPasswordException (line 105) | public FirebaseWeakPasswordException() : base()
    method FirebaseWeakPasswordException (line 114) | public FirebaseWeakPasswordException(String message) : base(message)
    method FirebaseWeakPasswordException (line 124) | public FirebaseWeakPasswordException(String message, Exception innerEx...

FILE: Auth/FirebaseAuthLink.cs
  class FirebaseAuthLink (line 8) | public class FirebaseAuthLink : FirebaseAuth
    method FirebaseAuthLink (line 10) | internal FirebaseAuthLink()
    method LinkToAsync (line 26) | public Task<FirebaseAuthLink> LinkToAsync(string email, string password)
    method LinkToAsync (line 37) | public Task<FirebaseAuthLink> LinkToAsync(FirebaseAuthType authType, s...

FILE: Auth/FirebaseAuthProvider.cs
  class FirebaseAuthProvider (line 15) | public class FirebaseAuthProvider : IDisposable, IFirebaseAuthProvider
    method FirebaseAuthProvider (line 30) | public FirebaseAuthProvider(FirebaseConfig authConfig)
    method SignInWithOAuthAsync (line 42) | public async Task<FirebaseAuthLink> SignInWithOAuthAsync(FirebaseAuthT...
    method SignInAnonymouslyAsync (line 54) | public async Task<FirebaseAuthLink> SignInAnonymouslyAsync()
    method SignInWithEmailAndPasswordAsync (line 67) | public async Task<FirebaseAuthLink> SignInWithEmailAndPasswordAsync(st...
    method CreateUserWithEmailAndPasswordAsync (line 80) | public async Task<FirebaseAuthLink> CreateUserWithEmailAndPasswordAsyn...
    method SendPasswordResetEmailAsync (line 91) | public async Task SendPasswordResetEmailAsync(string email)
    method LinkAccountsAsync (line 107) | public async Task<FirebaseAuthLink> LinkAccountsAsync(FirebaseAuth aut...
    method LinkAccountsAsync (line 121) | public async Task<FirebaseAuthLink> LinkAccountsAsync(FirebaseAuth aut...
    method Dispose (line 132) | public void Dispose()
    method SignInWithPostContentAsync (line 137) | private async Task<FirebaseAuthLink> SignInWithPostContentAsync(string...
    method GetProviderId (line 187) | private string GetProviderId(FirebaseAuthType authType)

FILE: Auth/FirebaseAuthType.cs
  type FirebaseAuthType (line 6) | public enum FirebaseAuthType

FILE: Auth/FirebaseConfig.cs
  class FirebaseConfig (line 6) | public class FirebaseConfig
    method FirebaseConfig (line 12) | public FirebaseConfig(string apiKey)
    method FirebaseConfig (line 22) | public FirebaseConfig(string apiKey, string apiKeyForPushNotification)

FILE: Auth/IFirebaseAuthProvider.cs
  type IFirebaseAuthProvider (line 8) | public interface IFirebaseAuthProvider
    method CreateUserWithEmailAndPasswordAsync (line 16) | Task<FirebaseAuthLink> CreateUserWithEmailAndPasswordAsync(string emai...
    method SendPasswordResetEmailAsync (line 23) | Task SendPasswordResetEmailAsync(string email);
    method SignInAnonymouslyAsync (line 29) | Task<FirebaseAuthLink> SignInAnonymouslyAsync();
    method SignInWithEmailAndPasswordAsync (line 37) | Task<FirebaseAuthLink> SignInWithEmailAndPasswordAsync(string email, s...
    method SignInWithOAuthAsync (line 45) | Task<FirebaseAuthLink> SignInWithOAuthAsync(FirebaseAuthType authType,...
    method LinkAccountsAsync (line 54) | Task<FirebaseAuthLink> LinkAccountsAsync(FirebaseAuth auth, string ema...
    method LinkAccountsAsync (line 63) | Task<FirebaseAuthLink> LinkAccountsAsync(FirebaseAuth auth, FirebaseAu...

FILE: Auth/User.cs
  class User (line 10) | public class User

FILE: Database/FirebaseClient.cs
  class FirebaseClient (line 13) | public class FirebaseClient
    method FirebaseClient (line 24) | public FirebaseClient(string baseUrl) : this(baseUrl, (t, s) => new Di...
    method FirebaseClient (line 33) | public FirebaseClient(string baseUrl, Func<Type, string, IDictionary<s...
    method FirebaseClient (line 50) | public FirebaseClient(string baseUrl, Func<Task<string>> authTokenAsyn...
    method FirebaseClient (line 61) | public FirebaseClient(string baseUrl, Func<Task<string>> authTokenAsyn...
    method Child (line 72) | public ChildQuery Child(string resourceName)

FILE: Database/FirebaseKeyGenerator.cs
  class FirebaseKeyGenerator (line 10) | public class FirebaseKeyGenerator
    method FirebaseKeyGenerator (line 23) | static FirebaseKeyGenerator()
    method Next (line 33) | public static string Next()

FILE: Database/FirebaseObject.cs
  class FirebaseObject (line 7) | public class FirebaseObject<T>
    method FirebaseObject (line 9) | internal FirebaseObject(string key, T obj)

FILE: Database/Http/HttpClientExtensions.cs
  class HttpClientExtensions (line 15) | internal static class HttpClientExtensions
    method GetObjectCollectionAsync (line 24) | public static async Task<IReadOnlyCollection<FirebaseObject<T>>> GetOb...
    method GetObjectCollection (line 43) | public static IEnumerable<FirebaseObject<object>> GetObjectCollection(...

FILE: Database/Http/PostResult.cs
  class PostResult (line 6) | public class PostResult

FILE: Database/ObservableExtensions.cs
  class ObservableExtensions (line 11) | public static class ObservableExtensions
    method AsObservableCollection (line 19) | public static ObservableCollection<T> AsObservableCollection<T>(this I...

FILE: Database/Offline/ExceptionEventArgs.cs
  class ExceptionEventArgs (line 8) | public class ExceptionEventArgs : EventArgs
    method ExceptionEventArgs (line 16) | public ExceptionEventArgs(Exception exception)

FILE: Database/Offline/OfflineCacheAdapter.cs
  class OfflineCacheAdapter (line 8) | internal class OfflineCacheAdapter<TKey, T> : IDictionary<string, T>, ID...
    method OfflineCacheAdapter (line 12) | public OfflineCacheAdapter(IDictionary<string, OfflineEntry> database)
    method CopyTo (line 17) | public void CopyTo(Array array, int index)
    method Contains (line 64) | public bool Contains(object key)
    method GetEnumerator (line 69) | IDictionaryEnumerator IDictionary.GetEnumerator()
    method Remove (line 74) | public void Remove(object key)
    method GetEnumerator (line 81) | public IEnumerator<KeyValuePair<string, T>> GetEnumerator()
    method GetEnumerator (line 86) | IEnumerator IEnumerable.GetEnumerator()
    method Add (line 91) | public void Add(KeyValuePair<string, T> item)
    method Add (line 96) | public void Add(object key, object value)
    method Clear (line 101) | public void Clear()
    method Contains (line 106) | public bool Contains(KeyValuePair<string, T> item)
    method CopyTo (line 111) | public void CopyTo(KeyValuePair<string, T>[] array, int arrayIndex)
    method Remove (line 116) | public bool Remove(KeyValuePair<string, T> item)
    method Add (line 121) | public void Add(string key, T value)
    method ContainsKey (line 126) | public bool ContainsKey(string key)
    method Remove (line 131) | public bool Remove(string key)
    method TryGetValue (line 136) | public bool TryGetValue(string key, out T value)

FILE: Database/Offline/OfflineEntry.cs
  class OfflineEntry (line 10) | public class OfflineEntry
    method OfflineEntry (line 21) | public OfflineEntry(string key, object obj, int priority, SyncOptions ...
    method OfflineEntry (line 35) | public OfflineEntry()
    method Deserialize (line 89) | public T Deserialize<T>()

FILE: Database/Offline/RealtimeDatabase.cs
  class RealtimeDatabase (line 18) | public partial class RealtimeDatabase<T> where T : class
    method RealtimeDatabase (line 36) | public RealtimeDatabase(ChildQuery childQuery, string elementRoot, Fun...
    method Put (line 58) | public void Put(string key, T obj, int priority = 1)
    method Post (line 69) | public string Post(T obj, int priority = 1)
    method Delete (line 83) | public void Delete(string key, int priority = 1)
    method Pull (line 93) | public void Pull(string key, int priority = 1)
    method AsObservable (line 109) | public IObservable<FirebaseEvent<T>> AsObservable()
    method InitializeStreamingSubscription (line 129) | private IDisposable InitializeStreamingSubscription(IObserver<Firebase...
    method SetAndRaise (line 136) | private void SetAndRaise(string key, OfflineEntry obj)
    method SynchronizeThread (line 142) | private async void SynchronizeThread()
    method GetLatestKey (line 161) | private string GetLatestKey()
    method PushEntriesAsync (line 166) | private async Task PushEntriesAsync(IEnumerable<KeyValuePair<string, O...
    method PullEntriesAsync (line 180) | private async Task PullEntriesAsync(IEnumerable<KeyValuePair<string, O...
    method ResetSyncOptions (line 197) | private void ResetSyncOptions(IEnumerable<string> entries)

FILE: Database/Offline/SyncOptions.cs
  type SyncOptions (line 6) | public enum SyncOptions

FILE: Database/Query/AuthQuery.cs
  class AuthQuery (line 8) | public class AuthQuery : ParameterQuery
    method AuthQuery (line 18) | public AuthQuery(FirebaseQuery parent, Func<string> tokenFactory, Fire...
    method BuildUrlParameter (line 28) | protected override string BuildUrlParameter(FirebaseQuery child)

FILE: Database/Query/ChildQuery.cs
  class ChildQuery (line 10) | public class ChildQuery : FirebaseQuery
    method ChildQuery (line 20) | public ChildQuery(FirebaseQuery parent, Func<string> pathFactory, Fire...
    method ChildQuery (line 31) | public ChildQuery(FirebaseClient client, Func<string> pathFactory)
    method AsRealtimeDatabase (line 44) | public RealtimeDatabase<T> AsRealtimeDatabase<T>(string filenameModifi...
    method BuildUrlSegment (line 54) | protected override string BuildUrlSegment(FirebaseQuery child)

FILE: Database/Query/FilterQuery.cs
  class FilterQuery (line 9) | public class FilterQuery : ParameterQuery
    method FilterQuery (line 21) | public FilterQuery(FirebaseQuery parent, Func<string> filterFactory, F...
    method FilterQuery (line 34) | public FilterQuery(FirebaseQuery parent, Func<string> filterFactory, F...
    method BuildUrlParameter (line 45) | protected override string BuildUrlParameter(FirebaseQuery child)

FILE: Database/Query/FirebaseQuery.cs
  class FirebaseQuery (line 18) | public abstract class FirebaseQuery : IFirebaseQuery, IDisposable
    method FirebaseQuery (line 29) | protected FirebaseQuery(FirebaseQuery parent, FirebaseClient client)
    method OnceAsync (line 48) | public async Task<IReadOnlyCollection<FirebaseObject<T>>> OnceAsync<T>()
    method OnceSingleAsync (line 64) | public async Task<T> OnceSingleAsync<T>()
    method AsObservable (line 81) | public IObservable<FirebaseEvent<T>> AsObservable<T>(string elementRoo...
    method BuildUrlAsync (line 90) | public async Task<string> BuildUrlAsync()
    method PostAsync (line 109) | public async Task<FirebaseObject<T>> PostAsync<T>(T obj, bool generate...
    method PatchAsync (line 135) | public async Task PatchAsync<T>(T obj)
    method PutAsync (line 148) | public async Task PutAsync<T>(T obj)
    method DeleteAsync (line 159) | public async Task DeleteAsync()
    method Dispose (line 171) | public void Dispose()
    method BuildUrlSegment (line 181) | protected abstract string BuildUrlSegment(FirebaseQuery child);
    method BuildUrl (line 183) | private string BuildUrl(FirebaseQuery child)
    method GetClient (line 195) | private HttpClient GetClient()
    method SendAsync (line 205) | private async Task<string> SendAsync<T>(HttpClient client, T obj, Http...

FILE: Database/Query/IFirebaseQuery.cs
  type IFirebaseQuery (line 12) | public interface IFirebaseQuery
    method OnceAsync (line 19) | Task<IReadOnlyCollection<FirebaseObject<T>>> OnceAsync<T>();
    method AsObservable (line 26) | IObservable<FirebaseEvent<T>> AsObservable<T>(string elementRoot = "");
    method BuildUrlAsync (line 32) | Task<string> BuildUrlAsync();

FILE: Database/Query/OrderQuery.cs
  class OrderQuery (line 8) | public class OrderQuery : ParameterQuery
    method OrderQuery (line 18) | public OrderQuery(ChildQuery parent, Func<string> propertyNameFactory,...
    method BuildUrlParameter (line 29) | protected override string BuildUrlParameter(FirebaseQuery child)

FILE: Database/Query/ParameterQuery.cs
  class ParameterQuery (line 8) | public abstract class ParameterQuery : FirebaseQuery
    method ParameterQuery (line 19) | protected ParameterQuery(FirebaseQuery parent, Func<string> parameterF...
    method BuildUrlSegment (line 31) | protected override string BuildUrlSegment(FirebaseQuery child)
    method BuildUrlParameter (line 41) | protected abstract string BuildUrlParameter(FirebaseQuery child);

FILE: Database/Query/QueryExtensions.cs
  class QueryExtensions (line 6) | public static class QueryExtensions
    method WithAuth (line 14) | public static AuthQuery WithAuth(this FirebaseQuery node, string token)
    method Child (line 25) | public static ChildQuery Child(this ChildQuery node, string path)
    method OrderBy (line 37) | public static OrderQuery OrderBy(this ChildQuery child, string propert...
    method StartAt (line 48) | public static FilterQuery StartAt(this ParameterQuery child, string va...
    method EndAt (line 59) | public static FilterQuery EndAt(this ParameterQuery child, string value)
    method EqualTo (line 70) | public static FilterQuery EqualTo(this ParameterQuery child, string va...
    method StartAt (line 81) | public static FilterQuery StartAt(this ParameterQuery child, double va...
    method EndAt (line 92) | public static FilterQuery EndAt(this ParameterQuery child, double value)
    method EqualTo (line 103) | public static FilterQuery EqualTo(this ParameterQuery child, double va...
    method LimitToFirst (line 114) | public static FilterQuery LimitToFirst(this ParameterQuery child, int ...
    method LimitToLast (line 125) | public static FilterQuery LimitToLast(this ParameterQuery child, int c...

FILE: Database/Query/QueryFactoryExtensions.cs
  class QueryFactoryExtensions (line 8) | public static class QueryFactoryExtensions
    method WithAuth (line 16) | public static AuthQuery WithAuth(this FirebaseQuery node, Func<string>...
    method Child (line 27) | public static ChildQuery Child(this ChildQuery node, Func<string> path...
    method OrderBy (line 39) | public static OrderQuery OrderBy(this ChildQuery child, Func<string> p...
    method OrderByKey (line 50) | public static OrderQuery OrderByKey(this ChildQuery child)
    method OrderByValue (line 61) | public static OrderQuery OrderByValue(this ChildQuery child)
    method OrderByPriority (line 72) | public static OrderQuery OrderByPriority(this ChildQuery child)
    method StartAt (line 83) | public static FilterQuery StartAt(this ParameterQuery child, Func<stri...
    method EndAt (line 94) | public static FilterQuery EndAt(this ParameterQuery child, Func<string...
    method EqualTo (line 105) | public static FilterQuery EqualTo(this ParameterQuery child, Func<stri...
    method StartAt (line 116) | public static FilterQuery StartAt(this ParameterQuery child, Func<doub...
    method EndAt (line 127) | public static FilterQuery EndAt(this ParameterQuery child, Func<double...
    method EqualTo (line 138) | public static FilterQuery EqualTo(this ParameterQuery child, Func<doub...
    method LimitToFirst (line 149) | public static FilterQuery LimitToFirst(this ParameterQuery child, Func...
    method LimitToLast (line 160) | public static FilterQuery LimitToLast(this ParameterQuery child, Func<...

FILE: Database/Streaming/FirebaseCache.cs
  class FirebaseCache (line 17) | public class FirebaseCache<T> : IEnumerable<FirebaseObject<T>>
    method FirebaseCache (line 24) | public FirebaseCache()
    method FirebaseCache (line 33) | public FirebaseCache(IDictionary<string, T> existingItems)
    method PushData (line 44) | public IEnumerable<FirebaseObject<T>> PushData(string path, string data)
    method GetEnumerator (line 146) | IEnumerator IEnumerable.GetEnumerator()
    method GetEnumerator (line 151) | public IEnumerator<FirebaseObject<T>> GetEnumerator()

FILE: Database/Streaming/FirebaseEvent.cs
  class FirebaseEvent (line 7) | public class FirebaseEvent<T> : FirebaseObject<T>
    method FirebaseEvent (line 15) | public FirebaseEvent(string key, T obj, FirebaseEventType eventType)

FILE: Database/Streaming/FirebaseEventType.cs
  type FirebaseEventType (line 6) | public enum FirebaseEventType

FILE: Database/Streaming/FirebaseServerEventType.cs
  type FirebaseServerEventType (line 3) | internal enum FirebaseServerEventType

FILE: Database/Streaming/FirebaseSubscription.cs
  class FirebaseSubscription (line 20) | internal class FirebaseSubscription<T> : IDisposable
    method FirebaseSubscription (line 35) | public FirebaseSubscription(IObserver<FirebaseEvent<T>> observer, IFir...
    method Dispose (line 58) | public void Dispose()
    method Run (line 64) | public IDisposable Run()
    method ReceiveThread (line 71) | private async void ReceiveThread()
    method ParseServerEvent (line 135) | private FirebaseServerEventType ParseServerEvent(FirebaseServerEventTy...
    method ProcessServerData (line 159) | private void ProcessServerData(FirebaseServerEventType serverEvent, st...

FILE: Notification/PushNotification.cs
  class PushNotification (line 9) | public class PushNotification
    method PushNotification (line 15) | public PushNotification(FirebaseConfig authConfig)
    method Send (line 20) | public async Task Send(string to, string title, string message)

FILE: Token/StreamToken.cs
  class StreamToken (line 7) | public class StreamToken<T> : IDisposable
    method StreamToken (line 12) | public StreamToken(IObservable<FirebaseEvent<T>> observable)
    method Where (line 17) | public StreamToken<T> Where(Func<FirebaseEvent<T>, bool> predicate)
    method Throttle (line 23) | public StreamToken<T> Throttle(TimeSpan timeSpan)
    method Subscribe (line 29) | public void Subscribe(Action<FirebaseEvent<T>> onDataAdded)
    method Dispose (line 32) | public void Dispose()

FILE: Token/TokenGenerator.cs
  class TokenGenerator (line 9) | public class TokenGenerator
    method TokenGenerator (line 18) | public TokenGenerator(string firebaseSecret)
    method CreateToken (line 28) | public string CreateToken(Dictionary<string, object> data)
    method CreateToken (line 39) | public string CreateToken(Dictionary<string, object> data, TokenOption...
    method computeToken (line 80) | private string computeToken(Dictionary<string, object> claims)
    method secondsSinceEpoch (line 85) | private static long secondsSinceEpoch(DateTime dt)
    method validateToken (line 91) | private static void validateToken(Dictionary<string, object> data, Boo...

FILE: Token/TokenOptions.cs
  class TokenOptions (line 5) | public class TokenOptions
    method TokenOptions (line 19) | public TokenOptions(DateTime? notBefore = null, DateTime? expires = nu...
Condensed preview — 47 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (131K chars).
[
  {
    "path": ".gitignore",
    "chars": 411,
    "preview": "#Autosave files\r\n*~\r\n\r\n#build\r\n[Oo]bj/\r\n[Bb]in/\r\npackages/\r\nTestResults/\r\n\r\n# globs\r\nMakefile.in\r\n*.DS_Store\r\n*.sln.cach"
  },
  {
    "path": "Auth/FirebaseAuth.cs",
    "chars": 1117,
    "preview": "namespace Firebase.Xamarin.Auth\n{\n    using Newtonsoft.Json;\n\n    /// <summary>\n    /// The firebase auth.\n    /// </su"
  },
  {
    "path": "Auth/FirebaseAuthException.cs",
    "chars": 3118,
    "preview": "using System;\nusing System.Runtime.Serialization;\n\nnamespace Firebase.Xamarin.Auth\n{\n\t/*\n\t * Sign In Exceptions \n\t */\n\t"
  },
  {
    "path": "Auth/FirebaseAuthLink.cs",
    "chars": 1451,
    "preview": "namespace Firebase.Xamarin.Auth\n{\n    using System.Threading.Tasks;\n\n    /// <summary>\n    /// The firebase auth which "
  },
  {
    "path": "Auth/FirebaseAuthProvider.cs",
    "chars": 8181,
    "preview": "namespace Firebase.Xamarin.Auth\n{\n\tusing System;\n\tusing System.Linq;\n\tusing System.Net.Http;\n\tusing System.Text;\n\tusing"
  },
  {
    "path": "Auth/FirebaseAuthType.cs",
    "chars": 527,
    "preview": "namespace Firebase.Xamarin.Auth\n{\n    /// <summary>\n    /// The type of authentication. \n    /// </summary>\n    public "
  },
  {
    "path": "Auth/FirebaseConfig.cs",
    "chars": 1390,
    "preview": "namespace Firebase.Xamarin.Auth\n{\n    /// <summary>\n    /// The auth config. \n    /// </summary>\n    public class Fireba"
  },
  {
    "path": "Auth/IFirebaseAuthProvider.cs",
    "chars": 3301,
    "preview": "namespace Firebase.Xamarin.Auth\n{\n    using System.Threading.Tasks;\n\n    /// <summary>\n    /// The auth token provider."
  },
  {
    "path": "Auth/User.cs",
    "chars": 2239,
    "preview": "namespace Firebase.Xamarin.Auth\n{\n    using System.ComponentModel;\n\n    using Newtonsoft.Json;\n\n    /// <summary>\n    /"
  },
  {
    "path": "Database/FirebaseClient.cs",
    "chars": 3084,
    "preview": "namespace Firebase.Xamarin.Database\n{\n    using System;\n    using System.Collections.Generic;\n    using System.Threading"
  },
  {
    "path": "Database/FirebaseKeyGenerator.cs",
    "chars": 3368,
    "preview": "namespace Firebase.Xamarin.Database\n{\n    using System;\n    using System.Text;\n\n    /// <summary>\n    /// Offline key ge"
  },
  {
    "path": "Database/FirebaseObject.cs",
    "chars": 712,
    "preview": "namespace Firebase.Xamarin.Database\n{\n    /// <summary>\n    /// Holds the object of type <typeparam name=\"T\" /> along wi"
  },
  {
    "path": "Database/GlobalSuppressions.cs",
    "chars": 251,
    "preview": "\n// This file is used by Code Analysis to maintain SuppressMessage \n// attributes that are applied to this project.\n// "
  },
  {
    "path": "Database/Http/HttpClientExtensions.cs",
    "chars": 2228,
    "preview": "namespace Firebase.Xamarin.Database.Http\n{\n    using System;\n    using System.Collections;\n    using System.Collections."
  },
  {
    "path": "Database/Http/PostResult.cs",
    "chars": 394,
    "preview": "namespace Firebase.Xamarin.Database.Http\n{\n    /// <summary>\n    /// Represents data returned after a successful POST to"
  },
  {
    "path": "Database/ObservableExtensions.cs",
    "chars": 1410,
    "preview": "namespace Firebase.Xamarin.Database\n{\n    using System;\n    using System.Collections.ObjectModel;\n\n    using Firebase.X"
  },
  {
    "path": "Database/Offline/ExceptionEventArgs.cs",
    "chars": 581,
    "preview": "namespace Firebase.Xamarin.Database.Offline\n{\n    using System;\n\n    /// <summary>\n    /// Event args holding the <see "
  },
  {
    "path": "Database/Offline/OfflineCacheAdapter.cs",
    "chars": 3811,
    "preview": "namespace Firebase.Xamarin.Database.Offline\n{\n    using System;\n    using System.Collections;\n    using System.Collecti"
  },
  {
    "path": "Database/Offline/OfflineEntry.cs",
    "chars": 2793,
    "preview": "namespace Firebase.Xamarin.Database.Offline\n{\n    using System;\n\n    using Newtonsoft.Json;\n\n    /// <summary>\n    /// "
  },
  {
    "path": "Database/Offline/RealtimeDatabase.cs",
    "chars": 8917,
    "preview": "namespace Firebase.Xamarin.Database.Offline\n{\n    using System;\n    using System.Collections.Generic;\n    using System."
  },
  {
    "path": "Database/Offline/SyncOptions.cs",
    "chars": 501,
    "preview": "namespace Firebase.Xamarin.Database.Offline\n{\n    /// <summary>\n    /// Specifies type of sync requested for given data"
  },
  {
    "path": "Database/Properties/AssemblyInfo.cs",
    "chars": 1183,
    "preview": "using System.Resources;\nusing System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropSer"
  },
  {
    "path": "Database/Query/AuthQuery.cs",
    "chars": 1165,
    "preview": "namespace Firebase.Xamarin.Database.Query\n{\n    using System;\n\n    /// <summary>\n    /// Represents an auth parameter in"
  },
  {
    "path": "Database/Query/ChildQuery.cs",
    "chars": 2693,
    "preview": "namespace Firebase.Xamarin.Database.Query\n{\n    using System;\n\tusing Firebase.Xamarin.Database;\n    using Firebase.Xamar"
  },
  {
    "path": "Database/Query/FilterQuery.cs",
    "chars": 2254,
    "preview": "namespace Firebase.Xamarin.Database.Query \n{\n    using System;\n    using System.Globalization;\n\n    /// <summary>\n    //"
  },
  {
    "path": "Database/Query/FirebaseQuery.cs",
    "chars": 7931,
    "preview": "namespace Firebase.Xamarin.Database.Query\n{\n    using System;\n    using System.Collections.Generic;\n    using System.Net"
  },
  {
    "path": "Database/Query/IFirebaseQuery.cs",
    "chars": 1252,
    "preview": "namespace Firebase.Xamarin.Database.Query\n{\n    using System;\n    using System.Collections.Generic;\n    using System.Th"
  },
  {
    "path": "Database/Query/OrderQuery.cs",
    "chars": 1185,
    "preview": "namespace Firebase.Xamarin.Database.Query\n{\n    using System;\n\n    /// <summary>\n    /// Represents a firebase ordering "
  },
  {
    "path": "Database/Query/ParameterQuery.cs",
    "chars": 1631,
    "preview": "namespace Firebase.Xamarin.Database.Query\n{\n    using System;\n\n    /// <summary>\n    /// Represents a parameter in fireb"
  },
  {
    "path": "Database/Query/QueryExtensions.cs",
    "chars": 5563,
    "preview": "namespace Firebase.Xamarin.Database.Query\n{\n    /// <summary>\n    /// Query extensions providing linq like syntax for fi"
  },
  {
    "path": "Database/Query/QueryFactoryExtensions.cs",
    "chars": 7714,
    "preview": "namespace Firebase.Xamarin.Database.Query\n{\n    using System;\n\n    /// <summary>\n    /// Query extensions providing linq"
  },
  {
    "path": "Database/Streaming/FirebaseCache.cs",
    "chars": 5983,
    "preview": "namespace Firebase.Xamarin.Database.Streaming\n{\n    using System;\n    using System.Collections;\n    using System.Collect"
  },
  {
    "path": "Database/Streaming/FirebaseEvent.cs",
    "chars": 960,
    "preview": "namespace Firebase.Xamarin.Database.Streaming\n{\n    /// <summary>\n    /// Firebase event which hold <see cref=\"EventType"
  },
  {
    "path": "Database/Streaming/FirebaseEventType.cs",
    "chars": 363,
    "preview": "namespace Firebase.Xamarin.Database.Streaming\n{\n    /// <summary>\n    /// The type of event. \n    /// </summary>\n    pub"
  },
  {
    "path": "Database/Streaming/FirebaseServerEventType.cs",
    "chars": 191,
    "preview": "namespace Firebase.Xamarin.Database.Streaming\n{\n    internal enum FirebaseServerEventType\n    {\n        Put,\n\n        Pa"
  },
  {
    "path": "Database/Streaming/FirebaseSubscription.cs",
    "chars": 7364,
    "preview": "namespace Firebase.Xamarin.Database.Streaming\n{\n    using System;\n    using System.Diagnostics;\n    using System.IO;\n   "
  },
  {
    "path": "Firebase.Xamarin.csproj",
    "chars": 6674,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.micro"
  },
  {
    "path": "Firebase.Xamarin.sln",
    "chars": 1495,
    "preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio 14\r\nVisualStudioVersion = 14.0.25123.0\r\n"
  },
  {
    "path": "LICENSE",
    "chars": 1095,
    "preview": "The MIT License (MIT)\r\n\r\nCopyright (c) 2016 ricardo\r\n\r\nPermission is hereby granted, free of charge, to any person obtai"
  },
  {
    "path": "Notification/PushNotification.cs",
    "chars": 1064,
    "preview": "using System;\nusing System.Net.Http;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Firebase.Xamarin.Auth;\n\nname"
  },
  {
    "path": "Properties/AssemblyInfo.cs",
    "chars": 1117,
    "preview": "using System.Resources;\r\nusing System.Reflection;\r\nusing System.Runtime.CompilerServices;\r\nusing System.Runtime.Interop"
  },
  {
    "path": "README.md",
    "chars": 6455,
    "preview": "# Firebase.Xamarin\nLight weight wrapper for Firebase Realtime Database REST API.\n## Installation\n```csharp\n// Install re"
  },
  {
    "path": "Token/StreamToken.cs",
    "chars": 849,
    "preview": "namespace Firebase.Xamarin.Token\n{\n\tusing System;\n\tusing System.Reactive.Linq;\n\tusing Firebase.Xamarin.Database.Streami"
  },
  {
    "path": "Token/TokenGenerator.cs",
    "chars": 3594,
    "preview": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Text;\n\n\nnamespace Firebase.Xamar"
  },
  {
    "path": "Token/TokenOptions.cs",
    "chars": 1081,
    "preview": "using System;\n\nnamespace Firebase.Xamarin.Token\n{\n\tpublic class TokenOptions\n\t{\n\t\tpublic DateTime? expires { get; priva"
  },
  {
    "path": "TokenGenerator.config",
    "chars": 73,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n</configuration>\n"
  },
  {
    "path": "packages.config",
    "chars": 1059,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Newtonsoft.Json\" version=\"9.0.1\" targetFramework=\"port"
  }
]

About this extraction

This page contains the full source code of the rlamasb/Firebase.Xamarin GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 47 files (118.9 KB), approximately 27.7k tokens, and a symbol index with 202 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!