cloud functions truncating logs - firebase

I currently rely on getting some information from cloud functions through console.log(information)
However, whenever the logs are long they are truncated when viewing on the browser. Scrolling bring up the next set of logs, hence the logs are incomplete (see attached image)
I'm aware that I can store his data in the database, but sometimes it's convenient viewing the logs as well
Anyone with a better way of going round this?

There is no easy workaround for this. You would have to build a string of whatever you want to log, split it into segments that fit on screen, then log those substrings separately. Or, you could write the log somewhere else temporarily, such a database.
This is a known issue, but please feel free to file a bug report to add your voice.

Related

How to handle required relationships in Firebase Realtime Database?

Local SQL
Locally in my application I have data models Foo and Bar, each stored in a separate SQL table.
Foo references Bar by its id, and it would be an error to have a Foo without its counterpart: Bar.
Sometimes they are shown together, other times only one is shown at a time, and its possible to edit one without it affecting the other.
Firebase Realtime Database
I am now investigating how I can best integrate it into my application to ensure a smooth sync & backup experience. Everything is pretty much straight forward; but I cannot wrap my head around how I can ensure that the above mentioned contract stays true.
There will be cases where Foo is synchronized; and Bar is only synchronized sometime later (consider a simple drop of network connectivity). During this period of time, the realtime database for this particular user would be considered to be in an illegal state. When connectivity returns, both Foo and Bar will eventually be synchronized and the entire thing can continue flowing - but what do I do until then? How can I safeguard against it? Do I need to, or am I looking for the answers in all the wrong places?
Some ideas that Ive been exploring:
Allow Bar to be missing locally. Consider Foo to be in a partial state whenever its bar is missing, e.g. it could be hidden in the UI until its "ready".
Somehow combine Foo and Bar locally, only save Foo when its Bar is available, etc.
Nest Bar inside Foo such that theyre always synchronized together. (This seems troublesome, I have a couple of relationships like Foo->Bar in my application and I would have to nest Bar inside all of them if this was the 'correct' way of handling it)
Please enlighten me if you can. Firebase isnt new to me, but synchronizing this kind of complex data with a multitude of relationships, is.
Additional context
While I cant share the actual Foo & Bar, I have an example which I believe resembles the challenge well.
Consider a chat application where there are messages, rooms and users.
You can post a message to a room, and you can edit a room name and color. A message cannot exist without a user and a room. When looking at it from a sync perspective, user, room and message now has to be synchronized "together" (or at the very least, a message would be invalid if it came through without the others).
Handling this with multi-path updates I would update all 3 everytime a message is posted/edited. Have I understood this correctly? If so, that would mean updating 1+N+N nodes in my own scenario. The N+N nodes wouldnt have any actual updated data, but would be included in the update to ensure all of it is synchronized together.
Further clarity
First, going back to the root of the problem - Foo references Bar by its id locally. If my application ends up in a state where either exist without the other, it would cause issues pretty much everywhere (this is what Im referring to as an illegal state, it cannot happen).
Considering ways to safeguard against it, Ive been recommended to use a multi-path update in firebase (I believe this is similar/identical to fan-out?). Ill try this approach shortly even though Im feeling reserved about it, just to verify whether what Im feeling is just from inexperience.
Im having a very hard time wrapping my head around the fact that if Foo changes locally, it would now also result in a query happening for Bar, such that both can be synchronized together to firebase. It sounds OK for such a simple scenario, however in practice it would mean something along the lines of: you make an edit to X and it gets saved locally, shortly thereafter a sync is happening to firebase, now 100:s of Y and Z are queried as well, and inserted into firebase in the same operation. Y & Z are likely already up to date in firebase at this point, and they havent changed locally.
I dont have much experience with these kinds of scenarios when it comes to firebase, my thinking goes along the lines of it being a huge waste of resources - Im sure firebase does a lot of work locally such that unnecessary synchronization work wont happen for data that hasnt actually changed, but I cant escape the thought that I would still be querying for 100:s and 100:s of complex models locally a lot, in cases where it doesnt seem necessary (surely another approach must exist where I tackle the problem from another angle?).
There will be cases where Foo is synchronized; and Bar is only synchronized sometime later (consider a simple drop of network connectivity).
If both writes come from the same client, consider using multi-path updates to prevent such partial updates.
I finally managed to solve this, hopefully this can help someone else out there that runs into the same challenge further down the line!
First and foremost, when registering ChildEventListener on a DatabaseReference; I get one notification with the latest version of the data, and then notifications each time the data changes.
Using that, I filter data by its "version" (basically a timestamp of when it was edited) so that only data that is newer than the latest local version of it is actually processed.
Anytime a Foo comes through and its Bar counterpart hasnt arrived yet, Ill mark it as a deferred-task that should be retried after the next sync operation is complete - in almost all cases, Bar will come through after Foo and the task will succeed on its next retry. In some cases a couple of other sync operations will come through before Bar, but my retry logic is all local and cheap, so I dont mind that.
If no Bar shows up during this lifetime of the application, its not a problem as the latest version of Foo will come through the next time the application is started, and the cycle just repeats itself until both Foo & Bar are available, at which point theyre inserted into my local database.
I dont know if this is the "correct" way to solve it. But using my knowledge, it is the best I could come up with that works, and I dont see any real downsides to it. Feel free to criticize it in the comments, or provide another answer if you think you have a better solution!
Thank you.

Looking for an efficient way to update the data

I'm writing a small game for Android in Unity. Basically the person have to guess whats on the photo. Now my boss wants me to add an additional function-> after successful/unsuccessful guess the player will get the panel to rate the photo (basically like or dislike), because we want to track which photos are not good/remove the photos after a couple of successful guesses.
My understanding is that if we want to add +1 to the variable in Firebase first I have to make the call and get it then we have to make a separate call with adding 1 to the value we got. I was wandering if there is a more efficient way to do it?
Thanks for any suggestions!
Instead of requesting firebase when you want to add ,you can request firebase in the beginning (onCreate like method) and save the object and then use it when you want to update it.
thanks
Well, one thing you can do is to store your data temporarily in some object, but NOT send it to Firebase right away. Instead, you can send the data to Firebase in times when the app/game is about to get paused/minimized; hence, reducing potential lags and increasing player satisfaction. OnApplicationPause(bool) is one of such functions that gets called when the game is minimized.
To do what you want, I would recommend using a Transaction instead of just doing a SetValueAsync. This lets you change values in your large shared database atomically, by first running your transaction against the local cache and later against the server data if it differs (see this question/answer).
This gets into some larger interesting bits of the Firebase Unity plugin. Reads/writes will run against your local cache, so you can do things like attach a listener to the "likes" node of a picture. As your cache syncs online and your transaction runs, this callback will be asynchronously triggered letting you keep the value up to date without worrying about syncing during app launch/shutdown/doing your own caching logic. This also means that generally, you don't have to worry too much about your online/offline state throughout your game.

How do you get the firebase log viewer to show line numbers?

Is there a way to get line numbers from log entries, for example when you do a:
console.log('Already a Thumbnail.');
It would be nice to see more than:
Instead it would be useful to also see the line number, particularly as functions get larger, is this possible? Thanks!
The Firebase Cloud Functions log doesn't have the ability to show line numbers as it's basically reading from stdout (or similar).
You may be able to glean further insight by viewing logs through the Cloud Functions Stackdriver Logging UI though.
Also, it's worth adding more details to your logs or using tags to distinguish between different console.log calls, for example:
console.log("ifThumbnailExists: Already a Thumbnail.");
And if you want to use the same log message on multiple lines, another line may use:
console.log("ifSmallImage: Already a Thumbnail.");
Ultimately the idea is that you should be able to tell what line or method the logs are coming from by providing additional details and using unique log messages.

Can you get a log file of 'reads' on specific RECID(Tablename) in Progress-4GL/Openedge at RunTime without access to Source Code?

I want to know which tables are being read by a query.
for each Customer where CustomerID = 12345.
Eventually this customer will be found in the following example, but progress must 'read' many tables before getting to customer 12345.
How do I know exactly which tables are read (By CustomerID), prior to getting to customer 12345?
*NOTE: I do not have access to modify the code being run for this selection. Ideally I would run a separate set of code that is executed at the same time as the customer query above to track the reads.
EDIT: More clearly - Can you track reads from a given program (.p) OR ProcessID and output either a RECID or the PrimaryKey to a file?
I understand the information is being read off the Disk and probably stored in a database buffer. So how would I get at the information in the database buffer?
You seem to be mixing up a few different things.
In a situation like your example where you FIND a specific record in one, and only one table then there is just a single record read. Progress will find that record by first scanning a relevant index. That might be 2 or 3 "logical reads" of the b-tree to get to the proper node. The record block and index blocks may, or may not be read from disk - that depends on what has happened previously.
There are "Virtual System Tables" available that can tell you how many READ operations take place against a particular table or index. But they do not trace the specific ROWID or other identifying data. _TableStat and _IndexStat are aggregates for all users on the system, _UserTableStat and _UserIndexStat are specific to a particular user's activity. You do need to set the -tablerangesize and -indexrangesize parameters adequately to take advantage of these.
If you have enabled the table and index statistics then you can use a tool like ProTop - http://protop.wss.com to get insight into this activity. Or you can write your own code.
OpenEdge Auditing does not track reads. That would be prohibitively expensive.
It's probably not really a good idea but, in theory, you could write FIND triggers for the tables you are interested in. That doesn't require access to the application source but you would need a development license. It will probably kill performance to do this though - so unless this is a non-production test environment that you just want to fiddle with I wouldn't really do that.
You mention wanting to know how you got to that point. That sounds more like you might need to have a "4gl trace". One easy way to get the stack trace of a running process is to execute:
$DLC/bin/proGetStack PID (UNIX)
or
%DLC%\bin\proGetStack PID (Windows)
This command will generate a "protrace.pid" file containing a 4gl stack trace and other interesting information.
There are also more complicated ways to get that info like using PROMON and the "client statement cache" or setting various log entry types at session startup. But proGetStack is pretty convenient and requires no code or scripting changes.
Some great options from Tom above. And all of them may be relevant to you. The option he only skirts around is the logging options. I feel obliged to expand on this because I'm giving a talk on it in a couple of weeks!
Assuming you are running a modern version of Progress, or even 10.2B08, then you have client logging available to you. Start your session with these additional options:
-clientlog "\somefolder\somefile.txt"
-logentrytypes "QryInfo:3"
This will log all the info of all the queries in your session to the file you specified above. If you navigate to the point in the system where you want to analyse your query and empty the logfile and save it, you can then run the offending query and see all the detail you need.
The output tells you all sorts of useful info, including the number of reads on each table, compared with the number returned to the user. You also get the index selected.
Using Tom's advice and/or this will get you what you need.

Using realm with infinite scrolling table view in swift

Im learning about using NSOperation, NSOperationQueue for my networking calls to deliver a more responsive UI in my apps' table view.
The result of the networking operation get stored into the realm and displayed in the table view.
This is an infinite scroll table view and as the user gets the end, more data is pulled into the app.
I am wondering what is the best design paradigm to use here, and where is the best spot to clear the realm. I don't want to inflate the app with useless data. I just want them to have data if they log back in with no network (airplane mode).
I also would like to know where the best spot to trigger these networking operations is? cellForRowAtIndexPath perhaps? I am not to sure since I usually just use Alamofire and trigger a network request in viewDidLoad. But these are not cancellable calls.
I've gone through the great tutorials on ray wenderlich but other then the playground examples, I am still not getting a real world application tutorial. If anyone knows of a good one on this subject let me know
thanks
This might be tricky to answer since it all depends on your app, the size/type of data it's displaying and how often you want to perform network fetches. In the end, it will be most likely be a compromise between what 'feels good' and how many system resources need to be consumed to make it happen.
In this particular scenario, Realm is being used as a caching mechanism and nothing more, so when to clear it should probably depend on how aggressively you wish to clear it.
If I was building a system like this, I would decide on a set number of the latest items I would always want to have available and save them in Realm. If the user then decided to start scrolling down beyond that limit, more data would be downloaded and appended to the Realm database as they went. Eventually the user will get tired and scroll back to the top (Or they might even just quit the app and restart from the top). At that point, it would be appropriate to trigger an operation to review the size of the Realm cache and remove as many items as necessary to bring it back to the desired size. If they start scrolling down again, then it's appropriate to just re-download that data.
Unlike SQLite, where items are copied into memory, Realm is very good at lazy-loading resources mapped from disk, so it's not necessary to worry about the number of Realm items in memory, more just the size of the Realm file on disk, which again depends on how big the data you're downloading is.
As for when to trigger another network operation to request more data, it's probably best to do it in tableView(_:willDisplay:forRowAt:). Depending on how large the data to download is (and the size of your table cells are), you should play with it until it feels natural when scrolling at a pretty normal speed. As a starting point, I'd recommend starting at maybe a whole screen-worth of table cells before hitting the bottom of the scroll view.
Good luck!

Resources