private IEnumerable <string> BuildSigningPayload(SigningOption options) => new List <string>
 {
     BuildActionMethod(options.Action),
     BuildContentMD5(options.ContentMD5),
     BuildContentType(options.ContentType),
     BuildExpiration(options.ExpireDate),
     BuilCanonicalizedResource(options.Path)
 };
        public string GetSignedUrl(SigningOption options)
        {
            ValidateOptions(options);

            var signingPayloadAsString = string.Join("\n", BuildSigningPayload(options));
            var encryptedBase64String  = EncryptPayload(signingPayloadAsString);

            return(PrepareSignedUrl(options, encryptedBase64String));
        }
        private string PrepareSignedUrl(SigningOption options, string signature) => new UriBuilder
        {
            Scheme = "https",
            Host   = $"{_firebaseConfiguration.StorageBaseAuthority.TrimSlashes().Replace("https://", "")}/{_credentials.GetDefaultBucket().TrimSlashes()}",
            Path   = options.Path.Trim().TrimSlashes(),
            Query  = $"GoogleAccessId={_credentials.GetServiceAccountEmail()}&Expires={BuildExpiration(options.ExpireDate)}&Signature={WebUtility.UrlEncode(signature)}"
        }

        .Uri.AbsoluteUri;
 private void ValidateOptions(SigningOption options)
 {
     if (options == null)
     {
         throw new ArgumentNullException(nameof(options));
     }
     if (options.ExpireDate.ToUnixSeconds() == 0)
     {
         throw new ArgumentOutOfRangeException(nameof(options.ExpireDate), "ExpireDate should be reasonable value");
     }
     if (string.IsNullOrWhiteSpace(options.Path))
     {
         throw new ArgumentNullException(nameof(options.Path));
     }
 }