I'm new here and a beginner architect. I'm helping the company I work to design our new product and since I start it, I read a lot about but is never enough.
I decided to use Mediator Pattern (with Mediatr) to call my application layer.
It's cool and I got how to work with it sometimes, but sometimes I get confused.
For example, when we publish a document on our new product, we uses a RequestHandler to do everything and check all rules it needs, it's fine and works like a charm, but, when I want just a quick data, it looks likes too much for just a simple thing.
As an example, every time the user do any kind of action on my web application, I have to check if he is still logged. We have single login per user, so, if the same user connect anywhere else, the older session expires. We do it by saving on database.
On every action of my app, I go to base and check if the session key is the same, as bellow.
var sessionKey = bibliotecaCookie.Value;
var mediator = controller.GetMediator();
var isUserSessionKeyValidRequest = new IsUserSessionKeyValidRequest()
{
sessionKey = sessionKey
};
var isValidSession = mediator.Send(isUserSessionKeyValidRequest).Result;
if (!isValidSession)
throw new UnauthorizedAccessException();
So, I have a RequestHandler (a Handler and a Request which returns a bool) just to check if the user session is ok.
When the handler catches this request, it goes to database and execute a simple rule which is "Is the passed session the same as the stored session key?".
Is it right? Is it the right approach? Did I understand it right?
Thanks in advance guys
Related
I am using Realm and building a Swift mobile app. I am really struggling to understand why and when Partial realms are created.
Here is my scenario:
a user logs in to the app and is brought to the first view controller.
In the first view controller in view did load, I am executing a query to get the current user, subscribing to the query and adding an observer to let me know when the data is synced:
let currentUserArr = realm.objects(DBUser.self).filter("id == %#", userId)
self.subscription = currentUserArr.subscribe(named: "current user")
self.subscriptionToken = self.subscription.observe(\.state, options: .initial) { state in
switch state {
case .creating:
print("creating")
case .pending:
print("pending")
case .complete:
print("complete")
self.artist = currentUserArr[0]
case .invalidated:
print("invalidated")
case .error(let err):
//seal.reject(err)
print(err)
}
}
This makes sense that if I check Realm Cloud, I have a new partial realm created with path as:
/db/__partial/DyeOy3OR4sNsqMi2OmDQQEzUa8F3/~7f11cf52
However, here is where my confusion starts. I log the user out. I log back in and again the code above executes. My thought would be that Realm would just reuse the partial already created, but instead it creates an entirely new partial.
/db/__partial/DyeOy3OR4sNsqMi2OmDQQEzUa8F3/~8bc7bc49
Is this by design or should I somehow be reusing partials rather than having a new one created every time a query is executed (even if it is executed by the same user)?
I have posted on Realm Forums as well:
https://forums.realm.io/t/realm-platform-realm-path-partial-s/2833
I don't believe I was actually logging the current sync user out. Upon further testing, once I did log out and log back in, the existing partial was re-used. This is a non-issue.
Should I use akavache as a primary local database in my xamarin forms application or a cache database on top of another sqlite database? Because I cant find any example of how to update, insert, delete data in akavache object. For example,
CacheItems= await BlobCache.LocalMachine.GetOrFetchObject<List<Item>>("CacheItems",
async () => await getdatafromAzure(recursive));
I am getting items from azure and store in local machine and these items are editable / deleteable or user can add a new item. How do I do it?
Anything saved to LocalMachine gets persisted physically to the device. So on app or device restart it'll still be there (if the user hasn't removed the app or cleared the data that is)
As far as how to access/save there's lots of good samples here
https://github.com/akavache/Akavache
Insert Object and Get Object are your basic access methods and then there's lots of extension methods like GetOrFetch, GetAndFetch, which are very useful
Here's a quick sample I haven't super tested to give one way to access stuff. It'd probably be better to use some of the extension methods but I figure an example like this is conceptually useful.
BlobCache.LocalMachine.GetObject<Tobject>(someKEy)
.Catch((KeyNotFoundException ke) => Observable.Return<Tobject>(null))
.SelectMany(result =>
{
//object doesn't exist in cache so create a new one
if (result == null)
result = new Tobject();
//apply whatever updates you are wanting to do
//result.SomeField = "bob";
//This will replace or insert data
return BlobCache.LocalMachine.InsertObject(someKEy, result);
})
.Subscribe();
It's really all pretty boring stuff :-p Just get an object and store an object. Under the hood Akavache does a lot of really cool optimizations and synchronizations around that boring stuff though allowing it to be boring for the rest of us
In most of my cases when I start up a VM I retrieve the object from the cache and then just store it as some property on the VM or inside some service class. Then when any changes are made to the object I just insert it into the cache
BlobCache.LocalMachine.InsertObject(someKEy, result).Subscribe()
At that point I know now if the app closes down I'll have the latest version of that object right when user starts up app
The examples I gave are more the full Rx way of accessing... What you have in your original question works fine
await BlobCache.LocalMachine.GetOrFetchObject<List<object>>("CacheItems",
async () => await getdatafromAzure(recursive));
That will basically check the cache if it doesn't exist then it goes to Azure...
LocalMachine stores to physical device, InMemory just stores to some internal dictionary that goes away once the app is unloaded from memory, and UserAccount works with NT remoting accounts.
The question itself is simple: For a Firebase app, How do you get data that was previously blocked after you login and it is no longer blocked?
As for the details that lead me to ask this question:
In this particular app, I use a simple layout with 2 main sub trees of the root tree, Users and Data. The Data tree is completely readable, anyone can read it at any time. The Users tree is almost the opposite, with the only exception being if you are logged in, then you can read a specific sub tree that is yours only. This leads to the problem that when you go to the page, this data that may be very important to you is blocked until you log in, and there is no way to retrieve it directly. After you log in, however, you now have permission to get that information, but because it was previously blocked, There seems to be no way to extract it.
I have scoured the docs and found only one trigger that might be useful, onAuth(), but even though I can run stuff after login, I cant actually get any data. The best I have gotten so far was a Firebase Reference to the specific sub tree I need, but I cant find any way to actually use that reference to get the Snapshot because it is after the page load. It seems the only option I have is to refresh the page after login and check for login on page load, but that is an awful lot of overhead. Is there some other way to get the data in a tree that you previously did not have permission for after you log in and do have permission to read it? Might there be some reference in the docs I can't find or don't understand that allows me to demand a new snapshot of a fire base reference that is not through triggers that can only be defined on pageload?
Frank van puffelen is right.
It is as simple as:
// setup and other code
ref = new Firebase(URL); //The firebase reference
myuserid = null; //Storage variable
myname = null; //Storage variable
//Other code
//Start of answer code
ref.onAuth(function(authData) { //ON login status change
if (ref.getAuth()) { //Are they logged in
myuserid = authData.uid; //Stores their UID for use
userbase = 'Users/' + authData.uid; //Get path to user info
ref.child(userbase).on("value", function(snapshot, prevChildKey) {
var newData = snapshot.val(); //get data
console.log(newData); //View data, confirmed it was what I wanted
myname = newData.name; //The important data I needed
})
}
})
It seems that so long as this listener is by the other listeners, it works. It runs every time the Authentication is changed, and if they are logged in, attaching a listener to the path with the information and getting it. I am sure there are better ways and probably some problems with this code, but it works for me.
I am currently stuck and cant find any answers anywhere!! So any help at all would be great!
Currently Im trying to create a sharedObject on a client and send a string from the client containing information based on phone hardware(e.g. accelerometer and geolocation) to ams. From here I want to be able to access information from the sharedObject on the server in the main.asc to use elsewhere!
This is where the problem is occurring I cant access the shared object sent by the client. I sent my shared object like this:
//It's a best practice to always check for a successful NetConnection
protected function onNetStatus(event:NetStatusEvent):void
{
switch(event.info.code)//Check for a successful NetConnection
{
case "NetConnection.Connect.Success"://If the netConnection is a success#
so = SharedObject.getRemote("Data", nc.uri, false);//
so.connect(nc);//connect the sharedObject to the srever
so.addEventListener(SyncEvent.SYNC, syncHandler);//The sync listener
publishCamera(); //Publish the video
case "NetStream.Publish.Start"://If the netStream is a success
//etc
}
}
//It's a best practice to always check for a successful NetConnection
protected function syncHandler(event:SyncEvent):void
{
so.setProperty("username", nameForData);
so.setProperty("age", 21);
so.setProperty("nationality", "irish");
trace("Local"+so.data.username);
Im just not sure how to access so from server side!! I know this works as I have tested it but if there are better ways to implement it I would be glad to get advice!Below is proof that it is hitting the server
Update
Still stuck so I am adding a bounty and updating where I am and how I have progressed!
I have the information hitting the server(sometimes its not constant I dont know why)
Example is sometimes I get this in the admin console most times i have no information in the properties tab
What I am trying to do is to get the file to save every time I flush() the shared object so I can use it elsewhere
My server code is straight from the adobe api this is how it looks in the main asc:
in my onAppStart() I added these lines at the end:
application.allowDebug = true;
application.clearOnAppStop = false;
var Shared = SharedObject.get("Data", true);
trace("Name: "+Shared.name);
trace("Username: "+Shared.getProperty("username"));
in my onAppStop() I added these lines at the end:
var Shared = SharedObject.get("Data", true);
Shared.clear();
The serverside code for shared objects is (almost) the same as the client side.
So using so.getProperty(propertyName) should do the job.
If not check the server side shared object reference from adobe. Maybe that helps.
Hope i didn't missunderstand your question.
I'm using mx.rpc.http.HTTPService to retrieve data from a web service. On the initial call to "loadWsData", HTTPservice accurately retrieves all the data.
However, on any and all subsequent calls HTTPService does not accurately retrieve the data; rather it always retrieves the first data set. I've confirmed that the web service is providing accurate data, both from web browsers and a ruby ws client script.
My code is below; any ideas on what could be the problem?
private function loadWsData(id:int):void
{
var webService:HTTPService = new HTTPService();
webService.url = "http://xxx.xxx.xxx.xxx:8080/profile/ + id;
webService.method = "GET";
webService.addEventListener(ResultEvent.RESULT, function(event:ResultEvent):void
{
var rawData:String = String(event.result);
var user:Object = JSON.decode(rawData).user; // User object always reflects the first data set retrieved.
....
....
});
webService.send();
}
Not sure what the issue might be, but I have a few suggestions on where to look.
First, there appears to be a bug in your code; the webService.url line is missing a quote mark. That could be messing up the URL you think you are sending. Odd, though, because I don't think what you have shown would compile, so I suspect this is just a cut-and-paste error when you posted this to StackOverflow, but I would trace out that URL just to be sure.
Also, I don't see code to remove the event listener (although it could be in the code you have abbreviated with ellipsis). Is it possible that there are lingering event listeners that are firing in addition to the ones you expect? If the original event listener fires, it will fire with the original data.
Another suggestion: instead of using a closure, try pulling it out to a separate function. That shouldn't be the issue, but maybe scope is playing a role here.
You could try to POST your results.
You might also add an event listener for FAULT, and see if there are any errors being thrown by your service request.