it-swarm.com.de

Google Dynamic Links mit .NET

Ich versuche, Google Firebase Dynamic Link auf meinem .NET-Kernprojekt zum Laufen zu bringen. Mein Code ist wie folgt

public static async Task<string> GetShortLink(string longLink)
{
    var service = AuthenticateServiceAccount("[email protected]", "Opt/Keys/quallogi-keys.json", new[] { "https://www.googleapis.com/auth/firebase" });
    var request = service.ManagedShortLinks.Create(new CreateManagedShortLinkRequest
    {
        DynamicLinkInfo = new DynamicLinkInfo
        {
            //DynamicLinkDomain = "https://quallogi.page.link",
            DomainUriPrefix = "quallogi.page.link",
            AnalyticsInfo = new AnalyticsInfo(),
            IosInfo = new IosInfo(),
            Link = "https://github.com/distriqt/ANE-Firebase/wiki/DynamicLinks---Create-Dynamic-Links",

        },

        Suffix = new Suffix { Option = "SHORT" },
        Name = "shortlink",


    });
    var response = await request.ExecuteAsync();
    return response.PreviewLink;
}

public static FirebaseDynamicLinksService AuthenticateServiceAccount(string serviceAccountEmail, string serviceAccountCredentialFilePath, string[] scopes)
{
    try
    {
        if (string.IsNullOrEmpty(serviceAccountCredentialFilePath))
            throw new Exception("Path to the service account credentials file is required.");
        if (!File.Exists(serviceAccountCredentialFilePath))
            throw new Exception("The service account credentials file does not exist at: " + serviceAccountCredentialFilePath);
        if (string.IsNullOrEmpty(serviceAccountEmail))
            throw new Exception("ServiceAccountEmail is required.");

        if (Path.GetExtension(serviceAccountCredentialFilePath).ToLower() == ".json")
        {
            GoogleCredential credential;
            using (var stream = new FileStream(serviceAccountCredentialFilePath, FileMode.Open, FileAccess.Read))
            {
                credential = GoogleCredential.FromStream(stream)
                     .CreateScoped(scopes);
            }

            return new FirebaseDynamicLinksService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = "Firebasedynamiclinks Service account Authentication Sample",
            });
        }
        else if (Path.GetExtension(serviceAccountCredentialFilePath).ToLower() == ".p12")
        {

            var certificate = new X509Certificate2(serviceAccountCredentialFilePath, "notasecret", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
            var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail)
            {
                Scopes = scopes
            }.FromCertificate(certificate));

            return new FirebaseDynamicLinksService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = "Firebasedynamiclinks Authentication Sample",
            });
        }
        else
        {
            throw new Exception("Unsupported Service accounts credentials.");
        }

    }
    catch (Exception ex)
    {
        throw new Exception("CreateServiceAccountFirebasedynamiclinksFailed", ex);
    }
}

aber wenn ich den Code google laufen lasse, wirft Ausnahme

Google.Apis.Requests.RequestError Interner Fehler. [500] Fehler [Meldung [Interner Fehler aufgetreten.] Speicherort [-] Grund [backendError] Domäne [global]]

 enter image description here

was war das Problem?

7
Gayan

Ich bin ein bisschen überrascht, dass du so weit gekommen bist wie du. Derzeit gibt es in dieser Bibliothek zwei Probleme:

  1. Bei Verwendung von ManagedShortLinks wird die Anzeige wie beschrieben vergrößert. Es wird jedoch nur so weit kommen, wenn Sie sich mit der zweiten Ausgabe befassen.
  2. Die ETag-Mitglieder sind nicht dekoriert und werden wie sie sind serialisiert. Sie werden einen Fehler wie folgt sehen:
Google.Apis.Requests.RequestError
Invalid JSON payload received. Unknown name "ETag" at 'dynamic_link_info.Android_info': Cannot find field.
Invalid JSON payload received. Unknown name "ETag" at 'dynamic_link_info.ios_info': Cannot find field.
Invalid JSON payload received. Unknown name "ETag" at 'dynamic_link_info': Cannot find field.
Invalid JSON payload received. Unknown name "ETag" at 'suffix': Cannot find field.
Invalid JSON payload received. Unknown name "ETag": Cannot find field. [400]

Ich habe keinen Weg gefunden, um ManagedShortLinks zu umgehen. ShortLinks funktioniert jedoch. Ich zeige dir, wie ich es gemacht habe.

       public async Task<string> GetDeepLink(Invitation inv)
       {
           var playId = _configurationProvider.GetSetting(AppSettingNames.GooglePlayAppId);
           var iosId = _configurationProvider.GetSetting(AppSettingNames.AppleAppStoreAppId);
           var domain = _configurationProvider.GetSetting(AppSettingNames.GoogleFirebaseDynamicLinkDomain);

           NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(string.Empty);

           queryString["Key1"] = "value1";

           var mslReq = new CreateShortDynamicLinkRequest();
           mslReq.DynamicLinkInfo = new DynamicLinkInfo();
           mslReq.DynamicLinkInfo.AndroidInfo = new AndroidInfo() { AndroidPackageName = playId };
           mslReq.DynamicLinkInfo.IosInfo = new IosInfo() { IosAppStoreId = iosId, IosBundleId = playId };
           mslReq.DynamicLinkInfo.DomainUriPrefix = $"https://{domain}";
           mslReq.DynamicLinkInfo.Link = $"https://www.example.com/?{queryString}";
           mslReq.Suffix = new Suffix() { Option = "SHORT" };
           var json = JsonConvert.SerializeObject(mslReq, Formatting.Indented, new CreateShortDynamicLinkRequestConverter());

           var request = _firebaseDynamicLinksService.ShortLinks.Create(new CreateShortDynamicLinkRequest());

           request.ModifyRequest = message =>
               message.Content = new StringContent(json, Encoding.UTF8, "application/json");

           var res = await request.ExecuteAsync();
           return res.ShortLink;
       }

Dies hängt von CreateShortDynamicLinkRequestConverter ab:

    public class CreateShortDynamicLinkRequestConverter : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            serializer.NullValueHandling = NullValueHandling.Ignore;
            var t = JToken.FromObject(value);
            var modified = t.RemoveFields("ETag");

            modified.WriteTo(writer);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override bool CanConvert(Type objectType)
        {
            return true;
        }

        public override bool CanRead => false;
    }

was wiederum von RemoveFields abhängt:

        // source: https://stackoverflow.com/a/31581951/773673
        public static JToken RemoveFields(this JToken token, params string[] fields)
        {
            JContainer container = token as JContainer;
            if (container == null) return token;

            List<JToken> removeList = new List<JToken>();
            foreach (JToken el in container.Children())
            {
                JProperty p = el as JProperty;
                if (p != null && (fields.Contains(p.Name)))
                {
                    removeList.Add(el);
                }
                el.RemoveFields(fields);
            }

            foreach (JToken el in removeList)
            {
                el.Remove();
            }

            return token;
        }

Letztendlich ist das große Problem hier die fehlende Dekoration der ETag-Mitglieder. Wir müssen das umgehen. Ich glaube, dass das Anpassen von BaseClientService.Initializer.Serializer, wenn der Dienst mit dem Konstruktor public NewtonsoftJsonSerializer(JsonSerializerSettings settings) instanziiert wird, es Ihnen ermöglicht, das zu verwendende Converters anzugeben, aber ich habe aufgehört, als es funktioniert. Die eigentliche Lösung besteht darin, die ETag-Mitglieder einfach so zu dekorieren, dass sie nicht an der Serialisierung teilnehmen (vorausgesetzt, dass nichts anderes kaputt geht!).

1
Adam Skinner