Does setting a Firebase value to the same value use bandwidth? - firebase

Firebase:
{exampleValue: "something";}
Javascript:
var ref = new Firebase(url + "/exampleValue");
ref.set("something");
I have a couple of questions around setting a value in Firebase to the same value, as shown above.
Does it use bandwidth for the user?
Does it count towards the bandwidth for my Firebase plan?

tl;dr: calling set() multiple times with the same value will use bandwidth each time.
You can easily test these things yourself. I just did the following: open the "Network" tab in the Chrome developer tools and find the WebSocket ("WS") that communicates with Firebase. In the "Frame" tab of that web socket you can see exactly what the Firebase client communicates with its server.
Then run the following in the developer console:
var newRef = ref.push();
This generates a new path/location, but does not send anything to the Firebase servers yet. Then:
newRef.set('This is a value');
This sets the value, so uses bandwidth.
Then I ran the same again:
newRef.set('This is a value');
This once again sent data to the Firebase server, so it uses bandwidth.
When you think about it, this also makes sense. The Firebase client knows only its local state. The value on the server might be different, for example because somebody else has changed the value. So when you tell it to set the value, it must send that command to the server to ensure that value actually gets written into the database.

Related

SignalR connected client in Clients.User(..) shouldn't exist

In my SignalR hub, I use the following method to check whether a user has an active connection:
var receivingClient = Clients.User(receiver);
if (receivingClient != null)
{
But I also track the online users manually over OnConnected \ OnDisconnected (in a ConcurrentDictionary). Now even when I shut down everything and start the server from scratch (e.g. IISExpress from VS), the above code part returns a result for a connection that doesn't exist.
Let's say I send from User A to user B. I start the server, go online with user A, then send a message to B: The above code returns a Microsoft.AspNetCore.SignalR.Internal.UserProxy<mySite.Services.ChatHub>.
I don't get it. Is it wrong to check for existing client connections with a null check? Should I exclusively rely on my manual tracking?
Thanks for some insight!
(PS: This is all on the same server - no load balancing / sharding)
Clients.User(receiver) returns a type that is used to invoke methods for the given user. It doesn't have anything to do with whether the user you pass in exists or not.
Is it wrong to check for existing client connections with a null check? Should I exclusively rely on my manual tracking?
Yes. Use manual tracking.

Calling .setPersistenceEnabled(false) when logging out of app, not working

In my Flutter/Dart mobile app I make use of Firebase RTDB persistence to enable offline use of the app.
My understanding is that to enable persistence you have to make the call, as per the following piece of code, before using any database references to eg. query the database. I use the following piece of code to enable persistence immediately after loading the app and it works fine:
FirebaseDatabase firebaseDatabase = FirebaseDatabase.instance;
bool _success = await firebaseDatabase.setPersistenceEnabled(true);
print(_success); // Prints true, so persistence is set 'on'.
When I logout of the app I attempt to turn persistence off with:
bool _success = await firebaseDatabase.setPersistenceEnabled(false);
print(_success); // Prints false, so persistence is still 'on', ie. the call failed.
I assume the reason persistence cannot be turned off is because there have been calls to db references prior to trying to switch it off.
This leads to three questions, I guess:
Should I be worried about turning it off at all, when I logout? The reason I attempt it is good house-keeping, mainly. I clean up shared preferences, close keepsyncd's, etc when logout is run. Also, though, the user can have multiple userids to login and I want to make sure that I am not retaining persisted data from their previous login id.
Related to 1, does setting persistence to false clear the cache of
data and potential queued calls to the db?
If the answers to 1 and 2 are 'yes', how can I switch persistence off given the code I'm using to do so keeps telling me it failed?
The typical way to handle this is to enable persistence once a user logs in.
Once disk persistence has been enabled and your app has used the database, it cannot be turned off. The documentation says this about it:
The returned Future will complete with true if the operation was successful or false if the persistence could not be set (because database references have already been created).
That last bit is clearly the case for you: you've been using the database already, which means that disk persistence is on.
To your specific questions:
Unfortunately the data in the local cache cannot be cleared up through the API at the moment. It is a valid feature request, but for now you'll have to assume that any data on the device can be seen by any user on that device (or device profile).
Disabling disk persistence keep the client from adding data to the cache. It does not clear any existing data in the cache.

Hideous performance using Azure mobile services MobileServiceSyncTable

I have a mobile service sync table that is giving me absolutely HORRENDOUS performance.
The table is declared as:
IMobileServiceSyncTable<Myclass> myclassTable;
this.client = new MobileServiceClient("my url here");
var store = new MobileServiceSQLiteStore(“localdb.db”);
store.DefineTable<Myclass>();
this.client.SyncContext.InitializeAsync(store);
this.myclassTable = client.GetSyncTable<Myclass>();
Than later in a button handler I’m calling into:
this.myclassTable.ToCollectionAsync();
The problem is, the performance is horrific. It takes at best minutes and most times just sits there indefinitely.
Is there anything in the above that I’ve done that would explain why performance is so absolutely terrible?
this.myclassTable.ToCollectionAsync();
For IMobileServiceSyncTable table, the above method would execute the SELECT * FROM [Myclass] sql statement against your local sqlite db.
The problem is, the performance is horrific. It takes at best minutes and most times just sits there indefinitely.
AFAIK, when working with offline sync, we may invoke the pull operation for retrieving a subset of the server data, then insert the retrieved data into the local store table. For await this.myclassTable.PullAsync(), it would send request and retrieve the server data with the MaxPageSize in 50, and the client SDK would send another request to confirm whether there has more data and pull them automatically.
In summary, I would recommend you checking with your code to locate the specific code which causes this poor performance. Also, you could leverage adding diagnostic logging, capturing the network traces via Fiddler to troubleshoot with this issue.

Guidelines for robust synchronisation of mobile client (iOS, Swift) with Realm Object Server

I have used the techniques in the RealmTask tutorial (https://realm.io/docs/tutorials/realmtasks/ ) to get a demonstration of synchronisation with the Realm Object Server working. However, as mentioned in realm mobile platform, how to connect while offline? , it is difficult to find design guidelines on realising a robust app in the presence of intermittent network connectivity. For example, the network might not be available when the app is first run, and in the tutorial example I think the login attempt would just time out after say 30 seconds.
From various sources, I have tried to outline an implementation approach on the client and have come up with the following:
=============================================================
At start-up of app
Create login credentials with
SyncCredentials.usernamePassword()
Check whether user credentials already exist using
SyncUser.all
If so, get the correct user using the appropriate key (UserId)
If a user is obtained, get the Realm configuration using
realmConfiguration = Realm.Configuration(SyncConfiguration(user, realmURL))
Attempt a log-in with
SyncUser.logIn with SyncCredentials
On completion, put the following on the main DispatchQueue (async)
realmConfiguration = Realm.Configuration(SyncConfiguration(user, realmURL))
if not logged in, repeat login attempts every N minutes until successful? E.g. to handle the situation when the network is unavailable when the app is started, but then becomes available?
Launch the rest of the app, making realmConfiguration available.
However, only access the Realm if realmConfiguration has been set up. Design the app so that it handles the scenario of realmConfiguration not being set up.
=============================================================
Is the above approach sensible, or is there a better solution?
Katsumi from Realm here. Our RealmTasks demo application may help you.
https://github.com/realm-demos/realm-tasks/tree/master/RealmTasks%20Apple
First, check whether the user has logged in or not at launched the app.
if configureDefaultRealm() {
window?.rootViewController = ContainerViewController()
window?.makeKeyAndVisible()
} else {
window?.rootViewController = UIViewController()
window?.makeKeyAndVisible()
logIn(animated: false)
}
https://github.com/realm-demos/realm-tasks/blob/master/RealmTasks%20Apple/RealmTasks%20iOS/AppDelegate.swift#L35
If the user has been logged in before, you can use user object that was cached before. (SyncUser.current or SyncUser.all)
If there is no cached user object (The user is the first time to use the app, or the user re-installs the app), show login view to signing up/in.
The former case (Use the cached user object) doesn't require network access, so you don't need to care about the offline situation.
The latter case (The user should signing up/in) requires network access, in that case, the best practice depends on the specification of the app. It is enough to show a just alert view that indicates requiring network for some apps, or use standalone Realm and then migrate synced realm after the app will be online.

NotificationHub Push Notification returns : The Token obtained from the Token Provider is wrong

I have Wp8.1 Silverlight app that receives push notification (WNS) from Mobileservice (the old azure service).
I therefore wanted to update to the new service because of the new features. I have now created/upgraded a new server to use App Service - Mobile App. And tested push notification with the sample app from azure (everything works).
Going back to my app WP8.1 -> Adding the new package Microsoft.Azure.Mobile.Client through NuGet (2.0.1), there is the issue that the Microsoft.WindowsAzure.Mobile.Ext does not contain the 'GetPush' extension. It seems like it is missing it? looking to the WP8 version, it only registers to MPNS, and I need WNS. So I do not know if any other assembly could be used.
Can I add another assembly reference?
Update
The following code lets me register the device on the server, and I can see the device register correctly. where the channelUri and the installationInformation are retrieved by the client and send to the server.
Installation ins = new Installation();
ins.Platform = NotificationPlatform.Wns;
ins.PushChannel = uTagAndChan.ChannelUri;
ins.Tags = uTagAndChan.Tags;
ins.InstallationId = uTagAndChan.installationInformation;
await hubClient.CreateOrUpdateInstallationAsync(ins);
Sending a test toast-notification to the registered tags, results in the following error :
The Token obtained from the Token Provider is wrong
Searching on this issue I found Windows Store App Push Notifications via Azure Service Bus. Which the proposed solution says to register to the notification hub directly from the app, I would rather not have the app to have directly access to the hub. But is this the only way? (mind you the answer was not accepted, but I will try it all though it is not a desired solution)
Update
Registering for notifications via client (WP8.1 Silverligt), makes a registration to MPNS, which I do not want.
The snippet on the server registers a WNS, the two registrations can be seen here:
The URI retrieval is done using
var channel = await Windows.Networking.PushNotifications.PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
which in the description states it returns a WNS. This seems to infer that the registration I am doing on the server (code snippet in the top) is correct and the registration on the client is faulty.
But the registration on the image seems wrong. Shouldn't the PNS Identifier be different for the two registrations? also expiration date seems wrong ?
How to mend this since the GetPush() (which was available in the sample registered the client correctly for notifications) does not exist in the NuGet package?
Update
I read one place that deleting and recreating the NotificationHub could help. I will try this today. Even IF it works, it would be more desirable to have the solution, and to know if the registrations are done correctly?
Temporary solution:
Deltede, recreated, inserted Package SID and Secret. And it works again (strange)!
Still interested in the underlying issue!
Deleted and recreated the service, setting all the same settings made it work again.
I had same issue with my UWP. But in my case I had issue with self signed certificate.
When I set the AppxPackageSigningEnabled property to True (in .csproj) then notifications stopped working and I got "The token obtained from the Token Provider is wrong" (Test send from Azure Portal).
The certificate must have same issuer as Publisher in Identity element in .appxmanifest file.

Resources