I have a Xamarin.Forms application that supports Android and iOS. I am trying to implement Google Analytics GA4. I followed this manual: https://thewissen.io/using-firebase-analytics-in-your-xamarin-forms-app/.
Now everything seems to be in place, and I should be ready to log events, as it is described in the manual:
IFirebaseAnalyticsService service = DependencyService.Get<IFirebaseAnalyticsService>();
service?.LogEvent("MyEventHere");
Or with the parameters:
service?.LogEvent(event, name, value);
Specifically, I need to log screen views (including screen name), button presses (including name of the functionality, e.g. Print etc), and errors (including fatal or not, and the message).
I cannot figure out though what the event and name can be. I assume, these values should not be just anything, but belong to a specific set. E.g. I found https://firebase.google.com/docs/analytics/screenviews examples for logging screen views. But those examples include Swift, Objective-C and some others, but not C#.
How can I do it in my Xamarin.Forms C# code? Or maybe I am wrong, and I can pass anything as event and as parameter?
Related
I'm working locally with Firestore for the web (Firebase version 9.8.2) and am trying to enable persistence. This works fine on initial page load, and also on refreshes, but once the source code is changed (even a trivial change like changing the text content of a DOM node), I receive the following error after calling enableIndexedDbPersistence:
Failed to obtain exclusive access to the persistence layer. To allow shared access, multi-tab synchronization has to be enabled in all tabs. If you are using experimentalForceOwningTab:true, make sure that only one tab has persistence enabled at any given time.
This same error occurs in the same way even if experimentalForceOwningTab:true is set.
According to the API Reference docs for enableIndexedDbPersistence, the property is now called forceOwnership (not experimentalForceOwningTab). This works!
I've nearly finished my lambda service for my smart home skill, and everything works great. The Echo is receiving my confirmations and correctly relaying their information. I'm now trying to build in error handling.
From the SHS API reference, there are a bunch of error messages listed that correspond to different circumstances. Are these errors supposed to change what Alexa says? Regardless of which one, if any, that I use Alexa just responds that the command doesn't work on that device. Right now I'm literally just using callback(err) and return the copy and pasted object from the API reference and still Alexa responds with the generic error.
It's easy to put in a bunch of constants to define error returns. It's harder to wire all of that into a firmware patch of a hardware device. Also, they only release an update to the SDK a few times a year. While they patch the hardware every couple of weeks.
Given that, I suspect that they put those error returns into the SDK to meet with a ship date with the SDK. More as placeholders than specific functionality. Over time, and if there is increased adoption of home skills, they will roll out updates to the hardware device that will take advantage of those returns.
My advice would be to use them. But not to expect there to be a difference right now. And don't mention differences in your documentation. If there is another place you can surface diagnostic information, you might want to do that so your customers can fix their problems.
The Here android SDK contains lots of log messages, but they go through a wrapper for the Android Log class, that by default does not actually log these messages. Is there a way to make it actually log these messages?
Im able to set a breakpoint in a decompiled class, bg.class, in the static init block, and set a = null, and that enables logging, but it seems like there must be a better and less tedious way to do that.
Sorry that is not supported :)
What would you like to achieve turning on logs? Generally our logs contains logs of trace messages that are not useful for 3rd party developers.
I'm a nascent coder creating a simple iOS app. I'm experimenting with coding push notifications for the first time and I have a simple question regarding the Parse Installation Object and a scenario where multiple users log on the same device (let's say a loner iPad at a library).
Based on the Parse documentation I've seen, when a user subscribes to a channel - let's say "The Giants" - it saves this info on the Installation Object. But if the user logs out and another user logs in, does Parse assume that we are to erase the previous channels? Should channels therefore be saved to the User class first, and only saved to Installation when a user logs in? And similarly how do we handle advanced targeting where I want to query Installation for a specific User objectId? Is the best practice to always leave the last user logged in listed as 'owner'/'user'?
If you find the library example impractical, also consider something like signing into your Spotify account on a friend's device in order to play a private playlist at a party. I know these are less common scenarios, but I want to make sure I know how to handle them.
I'm new to Push Notifications so I may be missing something fundamental here, but if any experienced developer can lend some advice as to how they handle this scenario, it would be greatly appreciated.
Store a reference to PFUsers when you save the installation. Add a field #"owner" and tag the pfuser to it.
After a user logs in, if they are not associated with the current installation, send an alert asking if they'd like to receive pushes on this device. If that's the case, resave and update the current installation. Otherwise leave it as is.
This is a tricky area, let me know what you come up with.
It's pretty rare that people will sign onto a service using someone else's phone, so I don't think its a huge issue if you want to just "see what happens" and if there's demand work it out.
I have 3 iOS apps using a single Parse application which supports push notifications for all 3 apps. I have a flag set on the project for the Release configuration for NDEBUG. I use #ifndef NDEBUG to set the boolean on a value I set on the current installation. This way it makes it easy to identify which installation that I can use for testing push notifications. I also use the appIdentifier value to filter to the application I am testing.
I also set other values as needed but these values are a good start.
if (debug) {
[currentInstallation setObject:[NSNumber numberWithBool:YES] forKey:#"debug"];
}
else {
[currentInstallation setObject:[NSNumber numberWithBool:NO] forKey:#"debug"];
}
To enable custom user preferences during publishing we would like to find out in the resolve step (inside a custom resolver) what the publishing user is (so not the user account configured for the Publisher service but the user that initiated the publish operation).
To find the original publishing user we would need to have access to the PublishTransaction object (specifically the Creator property); we cannot use the User property from the Session inside the custom resolver as this Session is created by the Publisher service (and would give us the service account).
To find the current PublishTransaction Mihai has provided us with an excellent hack.
In essence; if we can get our hands on an Engine object we can determine the context publish transaction.
In our custom resolver the Resolve method is called with four parameters:
public void Resolve(
IdentifiableObject item,
ResolveInstruction instruction,
PublishContext context,
ISet<ResolvedItem> resolvedItems
) { }
The item can be used to provide us with a Session object but neither an IdentifiableObject nor a Session hold a reference to the Engine.
The resolve instruction is just a set of data properties for the resolve.
The publish context (unfortunately not a PublishingContext) holds the publication and publication target only.
A ResolvedItem can give us access to the Session again but not the Engine.
My question (finally) would be two-fold:
1. have I missed any potential points where the context user account can be determined from (other than the PublishTransaction)?
2. have I missed any potential points where the Engine can be determined from the parameters the IResolver.Resolve() method is being called with?
Edit: I realize I left out the broader picture on why we want to customize the publish activity with extra metadata (from user preferences) because it is a bit of a long story;
What I ultimately need is to activate for a specific version of a component in the component template (by walking up the version list and finding a version that is linked to a dedicated marker component) but in order to do that I need to know what the marker component is. For this reason we publish the marker component (which will resolve all linked components and ultimately pages) and the custom resolver allowed us to push the TCMURI of the marker component into the session cache (making it accessible in the CT).
Now we want to set a "preference" for a specific marker component at a user level to allow smaller batches of assets to be published within this marker context (as opposed to publishing everything linked to the marker at once).
Because the TBBs running inside the CT actually DO have an Engine object available, we can use Mihai's method and determine the publishing user (as opposed to pushing the marker context from the resolver what we initially did) and in this way bypass the issue completely.
I was wondering why there is such a difference in information availability between a resolve and a render operation; both are afterall part of the same publishing context. I cannot help but feel I'm overlooking something very basic but maybe I'm not and accessing a publishing context or engine from the resolver is simply impossible.
Edit: as presumed by Dominic and confirmed by Nuno there is no "Engine" at the time of resolving; as such this half of my question has been answered.
That leaves
have I missed any potential points where the context user account can be determined from (other than the PublishTransaction)?
I went down this road before in a project (trying to get the user in a Resolver extension) and it was a world of pain.
I moved from a Resolver extension to a Render Extension, and even considered a Transport extension, just to go back to the simplest approach possible: a TBB.
Granted, my use case was different than yours, as it looks like you may want to change the resolving behavior based on the user (some users don't like link propagation, right? - if they're afraid of changing content, then they shouldn't change it ;-) ) but I ended up not implementing it that way.
I think there was an Enhancement Request to include more info about the user triggering publishing actions, but if that is implemented in the product it will be for Tridion 2013, not sure you can wait that long.
I'd guess that you can't get your hands on an engine at this point. After all, you're resolving, not rendering. You mention that you want to "enable user preferences", but you don't tell us much more about your actual problem, rather than the line of investigation you are currently following (which may or may not be a dead end).
What kind of user preferences are relevant to publishing, and why do you need to have them in the resolver?