谷歌动态链接与.NET

Gay*_*yan 7 c# firebase .net-core firebase-dynamic-links

我想在我的.net核心项目上获取google firebase动态链接工作,我的代码如下所示

public static async Task<string> GetShortLink(string longLink)
{
    var service = AuthenticateServiceAccount("gayan@empite.com", "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);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是当我运行代码谷歌抛出异常

Google.Apis.Requests.RequestError遇到内部错误.[500]错误[消息[遇到内部错误.]位置[ - ]原因[backendError]域[全局]]

在此输入图像描述

问题是什么?

Ada*_*ner 2

我有点惊讶你能走到这一步。目前,该库有两个问题:

  1. 当使用 ManagedShortLinks 时,它会像描述的那样爆炸。然而,如果你处理第二个问题,事情就到此为止了。
  2. 成员ETag未经修饰,并按原样序列化。您将看到如下错误:
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]
Run Code Online (Sandbox Code Playgroud)

我还没有找到解决 ManagedShortLinks 的方法。不过,ShortLinks会起作用的。我将向您展示我是如何做到的。

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]
Run Code Online (Sandbox Code Playgroud)

这取决于CreateShortDynamicLinkRequestConverter

    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;
    }
Run Code Online (Sandbox Code Playgroud)

这又取决于RemoveFields

        // source: /sf/answers/2210736601/
        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;
        }
Run Code Online (Sandbox Code Playgroud)

归根结底,这里最大的问题是成员缺乏装饰ETag。我们需要解决这个问题。我相信,BaseClientService.Initializer.Serializer在使用构造函数实例化服务时进行自定义public NewtonsoftJsonSerializer(JsonSerializerSettings settings)将允许您指定Converters要使用的,但当我让它工作时我就停止了。真正的解决办法是简单地装饰 ETag 成员,使其不参与序列化(前提是不会破坏其他任何内容!)。