How to use CloudFunctions in a Xamarin project - c#

Is there a tutorial on how to properly call a cloud function using Xamarin.Firebase.iOS.CloudFunctions? Or how to setup a regular http request for it, without the library?
I set up my function like this:
exports.IsAppleSubscriptionActive = functions.https.onCall(async (data, context) => {});'''
and deployed it like this:
firebase deploy --only functions
and got and url like this:
https://[region]-[project-id].cloudfunctions.net/IsAppleSubscriptionActive
On the client I installed the nuget and I try calling:
var result = await CloudFunctions.DefaultInstance.HttpsCallable("IsAppleSubscriptionActive").CallAsync(payloadToSend);
where payloadToSend is a NSDictionary.
I get
Foundation.NSErrorException: Error Domain=com.firebase.functions Code=13 "INTERNAL" UserInfo={NSLocalizedDescription=INTERNAL}
What am I missing? I feel like the native tutorials aren't helping either.
When using a regular http request I get a 500 status, in the logs I see something related to permissions accessing the secret manager (I use it for some api keys).

Ok, so there was nothing wrong with the code, I just wasn't giving the proper permissions to the proper user (I was using Secret Manager in my cloud function)

Related

DevOps API - C# Retrieve list of Projects using Client Libraries

I am trying to get THIS example to work (.Net Client Libraries example) - however everything I have attempted results in an error:
Basic authentication requires a secure connection to the server.
There is another example using the REST Api at the top of the page I linked and this works perfectly fine. For some reason, I just cant get this working using the libraries!
My code looks like this:
Uri uri = new Uri("http://adtfs:8080/tfs/{MyCompany}");
string personalAccessToken = "MyPATString";
VssBasicCredential credentials = new VssBasicCredential("", personalAccessToken);
using (ProjectHttpClient projectHttpClient = new ProjectHttpClient(uri, credentials))
{
IEnumerable<TeamProjectReference> projects = projectHttpClient.GetProjects().Result;
}
As I mentioned, using the same URL and PAT in the REST API example works fine, but for the libraries, I just cant get beyond the error mentioned above.
Am I missing something or can anyone suggest anything else I could try please?
Change http=>https from http://adtfs:8080/tfs/{MyCompany} to https://adtfs:8080/tfs/{MyCompany} ... easiest answer there was I guess works glad it helped ... but just as precautionary tale, I'll add this for posterity, you should use https anyways if the server supports it (had an app that was working sometimes slow, sometimes fast and I couldn't figure out why until I saw this https://httpvshttps.com, turns out the https tunnel was always being recreated cause I put http instead of https and the server was set to always switch to https).

403 Message: Legacy People API has not been used in project [duplicate]

This question already has an answer here:
Legacy People API has not been used in project
(1 answer)
Closed 1 year ago.
Google API is active but give error ;
Legacy People API has not been used in project before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/legacypeople.googleapis.com/overview?project= then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
You don't need to install any other APIs like Google Drive API, Google Sheets API or other except Google+ API,
The error is coming because of "passport-google-oauth": "^1.0.0"
Just change the version "passport-google-oauth": "^1.0.0" to "passport-google-oauth": "^2.0.0" and remove node_modules and package.lock.json file and run "npm i"
That's it
Before the Google+ API Shutdown on March 7, 2019, the people.get and people.getOpenIdConnect methods were available for requesting a person’s profile.
To avoid breaking existing integrations with these methods supporting sign-in, a new minimal implementation only returns basic fields necessary for that functionality, such as name and email address, if authorized by the user. The Legacy People API is where these methods will remain available for existing callers at the existing HTTP endpoints.
The Legacy People API serves a limited new implementation of the legacy Google+ API people.get and people.getOpenIdConnect methods necessary for maintaining sign-in functionality. It is available to existing callers of the original methods that haven't migrated to recommended replacements such as Google Sign-in or Google People API at the time of the Google+ API shutdown.
enter link description here
Thanks
In this case, I'm facing the same issue. This is what I've done to fix it.
Situation:
NodeJS ver 8
"passport-google-oauth": "^1.0.0"
Using Google+ API as Google Sign-in
When I run the apps and click Sign in with Google, what happened then?
Server error
Error log: Legacy People API has not been used in project "xxxx" before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/legacypeople.googleapis.com/overview?project=xxxx then retry.
How I solve it?
Go to Google Console
Click on Google+ API under Social APIs, then click Enable API
Click on Google Drive API under G Suite, then click Enable API
Click on Google Sheets API under G Suite, then click Enable API
Update "passport-google-oauth": "^1.0.0" to "passport-google-oauth": "^2.0.0"
in package.json
remove package-lock.json and node_modules folder (to ensure everything is clear)
run this command : npm install
It works now!
Note: my previous code still using profile._json.image.url to get profile image. Actually, this response was not there anymore. So I delete this code.
Goodbye Google+
Thank you Google People API.
Enabling the Google Contacts API and the Google+ API fixed this issue for me.
Hi I recently stumbeled on the same issue. As explained by Ilan Laloum, Google+ API as been decommissionned completely for new projects.
I found that Google People API works in a similar way. The following example is based on the Bookshelf tutorial in GCP. Source code can be seen here: https://github.com/GoogleCloudPlatform/golang-samples/tree/appengine/go111/cloudsql/getting-started/bookshelf (branch appengine/go111/cloudsql)
import people "google.golang.org/api/people/v1"
...
// retrieves the profile of the user associated with the provided OAuth token
func fetchProfile(ctx context.Context, tok *oauth2.Token) (*people.Person, error) {
peopleService, err := people.NewService(ctx, option.WithTokenSource(bookshelf.OAuthConfig.TokenSource(ctx, tok)))
if err != nil {
return nil, err
}
return peopleService.People.Get("people/me").
PersonFields("names,coverPhotos,emailAddresses").
Do()
}
This method needs a context and a OAuth token, just like Google+ API used to. The peopleService is initialized in a similar fashion.
The peopleService.People.Get("people/me") prepares a query that fetches the profile of the connected user. Then PersonFields("names,coverPhotos,emailAddresses") is a filter on profile fields. This part of the request is mandatory. Eventually Do() will execute the request.
This issue can be fixed using the passport-google-token
npm install passport-google-token
const GoogleStrategy = require('passport-google-token').Strategy;
// Google OAuth Strategy
passport.use('googleToken', new GoogleStrategy({
clientID: CLIENT_ID,
clientSecret: CLIENT_SECRET
}, async (accessToken, refreshToken, profile, done) => {
try {
console.log('creating a new user')
const newUser = new User({
google: {
id: profile.id,
email: profile.emails[0].value
}
});
await newUser.save();
done(null, newUser);
} catch (error) {
done(error, false, error.message);
}
}));
I was also having the same issue but with my Rails app. So I resolved it by upgrading the omniauth gems by running bundle update devise omniauth omniauth-google-oauth2 in terminal.
I also faced the same issue. This issue may occur for using the old library, enable the google people Api for your project, and download the library as per your php version from this link and integrate it.

401 Unauthorized when querying durable function status

I need some help with Azure Durable Functions.
I created a new durable function with VS Code in C# and deployed it to Azure via the VS Code azure function extension. The function app resource was already created manually in the portal. I use
FUNCTIONS_WORKER_RUNTIME: dotnet
FUNCTIONS_EXTENSION_VERSION: ~2
I can trigger the creation of an durable task and but when I query the status with the statusQueryGetUri, I only get a 401 Unauthrized. The http trigger of the function itself is anonymous and does not require authentication (for debug purpose only).
The requests look like this (I used Postman to send the requests):
HTTP POST https://{function-app}.azurewebsites.net/api/SayHello_HttpStart
Response:
{
"id": "da3259a462084e86a34f8ce9859a6ed6",
"statusQueryGetUri": "https://{function-app}.azurewebsites.net/runtime/webhooks/durabletask/instances/da3259a462084e86a34f8ce9859a6ed6?taskHub=DurableFunctionsHub&connection=Storage&code=ua4tHacVv9JDH5phKCJI1OdKGXQSB/MMUX8WIv1E0OyZANqrRY3L/g==",
"sendEventPostUri": "https://{function-app}.azurewebsites.net/runtime/webhooks/durabletask/instances/da3259a462084e86a34f8ce9859a6ed6/raiseEvent/{eventName}?taskHub=DurableFunctionsHub&connection=Storage&code=ua4tHacVv9JDH5phKCJI1OdKGXQSB/MMUX8WIv1E0OyZANqrRY3L/g==",
"terminatePostUri": "https://{function-app}.azurewebsites.net/runtime/webhooks/durabletask/instances/da3259a462084e86a34f8ce9859a6ed6/terminate?reason={text}&taskHub=DurableFunctionsHub&connection=Storage&code=ua4tHacVv9JDH5phKCJI1OdKGXQSB/MMUX8WIv1E0OyZANqrRY3L/g==",
"rewindPostUri": "https://{function-app}.azurewebsites.net/runtime/webhooks/durabletask/instances/da3259a462084e86a34f8ce9859a6ed6/rewind?reason={text}&taskHub=DurableFunctionsHub&connection=Storage&code=ua4tHacVv9JDH5phKCJI1OdKGXQSB/MMUX8WIv1E0OyZANqrRY3L/g==",
"purgeHistoryDeleteUri": "https://{function-app}.azurewebsites.net/runtime/webhooks/durabletask/instances/da3259a462084e86a34f8ce9859a6ed6?taskHub=DurableFunctionsHub&connection=Storage&code=ua4tHacVv9JDH5phKCJI1OdKGXQSB/MMUX8WIv1E0OyZANqrRY3L/g=="
}
The Get Request is then simply:
GET https://{function-app}.azurewebsites.net/runtime/webhooks/durabletask/instances/da3259a462084e86a34f8ce9859a6ed6?taskHub=DurableFunctionsHub&connection=Storage&code=ua4tHacVv9JDH5phKCJI1OdKGXQSB/MMUX8WIv1E0OyZANqrRY3L/g==
Did I miss some configuration I have to set to allow access to the uri? What logs might help me figure out what the problem is?
When I run the code locally there are no problems and everything works as expected.
Thanks a lot for all help!
Note that the statusQueryGetUri is an admin endpoint which always requires a System Key.
GET <rootUrl>/runtime/webhooks/durabletask/instances/<GUID>
?taskHub={taskHub}
&connection={connection}
&code={systemKey}
As an alternative, you could also set the x-functions-key header of the http request with this key.
More info on the usage of the HTTP endpoints in the docs.

Access WebJob Information via Microsoft.Azure.Management.Fluent in C#

Using Information via Microsoft.Azure.Management.Fluent I'm trying to get to information about Web Jobs. I'm able to use it to get information about Web Apps, Service Buses, Resource Groups, App Services, etc.
But I haven't been able to find a way to get to the Web Job level. In Azure the Web Jobs are located at the level
https://ms.portal.azure.com/#resource/subscriptions/{SubId}/resourceGroups/{ApServiceName}/providers/Microsoft.Web/sites/{ApServiceName}/webJobs
Using Microsoft.Azure.Management.Fluent I haven't been able to find a way to get to the Web Jobs level. Is this possible via the Microsoft.Azure.Management.Fluent?
Is this possible via the Microsoft.Azure.Management.Fluent?
Based on my exerpience, No. According to Azure SDK source code, it seems that there is no way to get the WebJob level.
If we want to get WebJob level, Azure supplies the WebJob API for us to operate on WebJob. About authorization for the WebJob API, we could refer to the this blog.
I had a need to execute some management API code for WebJobs and found that it is now possible, although it's not easy to find it in the API documentation.
You can do it by installing the Microsoft.Azure.Management.AppService.Fluent package (I think it's also possible to do it the non-fluent management SDK too, although I didn't try this).
Getting access to the methods for managing a WebJob can be done like this:
using Microsoft.Azure.Management.Fluent;
using Microsoft.Azure.Management.ResourceManager.Fluent;
using Microsoft.Azure.Management.ResourceManager.Fluent.Authentication;
class MyWebJobsManagementClass
{
public async Task DoSomeWebJobsManagement()
{
var jobs = await Azure
.Authenticate() // See the docs for how to authenticate with this SDK
.WithSubscription("your-subscription-id")
.AppServices
.Inner
.WebApps
.ListWebJobsWithHttpMessagesAsync("resource-group-name", "app-service-name")
}
}
It's through the non-obvious AppServices.Inner that you can get a reference to an IWebAppsOperations instance which then lets you perform quite a few operations on the WebJobs, including starting and stopping them.
Authentication Side note
If you're looking for a way to authenticate with Azure.Identity, instead of the file based credentials approach they used to use with these older SDKs, then there is a way to achieve this even though it's not supported "out-the-box".
There's a GitHub repo which contains an example of how to achieve this. I think it's by one of the developers on the Microsoft team, but isn't officially supported by Microsoft. There is no NuGet package for it and they recommend just copying the bits you need.
I actually found that the code in that sample repo was overly complex for my needs and in my case that all I needed was this. Note, I've copied this from my F# project without testing it, so I might have made a mistake in the conversion to C#, but hopefully it's close enough that you get the idea.
class AzureIdentityFluentCredentialAdapter : AzureCredentials
{
public AzureIdentityFluentCredentialAdapter(string tenantId)
: base(default(DeviceCredentialInformation), tenantId, AzureEnvironment.AzureGlobalCloud)
{
}
public override Task ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var creds = DefaultAzureCredential() // Use the new Azure.Identity library to get access tokens
var accessToken = await creds.GetTokenAsync(
new TokenRequestContent(new [] { "https://management.azure.com/.default" }),
cancellationToken);
return await TokenCredentials(accessToken.Token)
.ProcessHttpRequestAsync(request, cancellationToken);
}
}
This example doesn't do any token caching, but for my purposes I wasn't too bothered about this. It's also hardcoded the scope that I request the token for because I knew I was only going to be using this with the Azure management API.

Google Datastore authentication issue - C#

I'm trying to connect to the Google Datastore on my account with service account credentials file (which I've created according to the documentation), but I'm encountering with authentication error while trying to insert an entity:
Grpc.Core.RpcException: Status(StatusCode=Unauthenticated,
Detail="Exception occured in metadata credentials plugin.")
My code is:
var db = DatastoreDb.Create("myprojectid");
Entity entity = new Entity{
Key = db.CreateKeyFactory("mykindname").CreateIncompleteKey()
};
var keys = await db.InsertAsync(new[] { entity });
The GOOGLE_APPLICATION_CREDENTIALS variable refers to the credentials file and when calling GoogleCredential.GetApplicationDefaultAsync() to see if the credentials object is valid it indeed looks good...
I saw some earlier examples which used the GetApplicationDefaultAsync function togehether with some DatastoreService object - but I couldn't find the DatastoreService object (probably it was there in old versions...) in the latest .Net API: Google.Cloud.Datastore.V1
Notice that I don't want to use the other authenticaiton methods:
1) Using the gcloud cli.
2) Running from Google environment (app engine for example).
Any idea how to solve this?
After the great help of Jon Skeet the issue was solved.
The authentication issues can occur if you don't reference all the required Datastore dlls. Make sure that all the dlls are referenced on the project that are running the calls to the Datastore.
I've added the Google Datastore lib via the NuGet to my test project and everything worked!
Notice that in such cases it is recommended to enable gRPC logging. `(For exmaple: GrpcEnvironment.SetLogger(new ConsoleLogger()), there you'll probably see if there were issues loading several dlls...
Authentication can be broken if your system clock is significantly incorrect. Check your system time, and fix it if necessary, then try authenticating against Datastore again.

Categories