<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Niamh Power on Medium]]></title>
        <description><![CDATA[Stories by Niamh Power on Medium]]></description>
        <link>https://medium.com/@niamhpower?source=rss-61de4ad69c14------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*tX498oJpxgqnoWz7F1EW8A.jpeg</url>
            <title>Stories by Niamh Power on Medium</title>
            <link>https://medium.com/@niamhpower?source=rss-61de4ad69c14------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 24 Apr 2026 05:22:51 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@niamhpower/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Firebase at Google I/O]]></title>
            <link>https://medium.com/@niamhpower/firebase-google-io-d0f6cb58daf8?source=rss-61de4ad69c14------2</link>
            <guid isPermaLink="false">https://medium.com/p/d0f6cb58daf8</guid>
            <category><![CDATA[analytics]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[firebase]]></category>
            <category><![CDATA[google]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Niamh Power]]></dc:creator>
            <pubDate>Wed, 29 May 2019 17:31:00 GMT</pubDate>
            <atom:updated>2019-05-29T17:31:00.821Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*maM5nYmRPxJ5AnuQ8jMjPA.png" /><figcaption><a href="https://firebase.googleblog.com/2019/05/whats-new-Google-IO-2019.html">https://firebase.googleblog.com/2019/05/whats-new-Google-IO-2019.html</a></figcaption></figure><p>I’m sure a lot of you are aware of or even attended Google I/O earlier this month. In Liverpool, we hosted an I/O extended event to live stream the keynote, and it was great to see so many local developers and enthusiasts turn up to watch it with us, even with Liverpool playing in the Champions League that night!</p><p>A common topic at the conference was of course Firebase. With 14 different talks concerning it, it’s safe to say there was a variety of new features to learn about. I’ve spent the last few weeks catching up with these talks, and I thought I would share what I’ve found.</p><h3>What’s New in Firebase</h3><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Fx8qTEMkZCPs%3Fstart%3D796%26feature%3Doembed%26start%3D796&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Dx8qTEMkZCPs&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2Fx8qTEMkZCPs%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/1940915abf862eca2d47fe3fea834101/href">https://medium.com/media/1940915abf862eca2d47fe3fea834101/href</a></iframe><p>An obvious choice, but a good one. This talk highlights all the new and sparkly features Firebase is bringing to us developers in 2019.</p><p>This talk combines live demos, case studies, and code examples, and is a great way to quickly understand what to try out next, and how they might help you as a developer.</p><p>A particular highlight for me is AutoML. I’ve always found Firebase ML really interesting but felt it inaccessible as I have no idea how to start without a pre-populated data set. It’s really exciting to see Firebase come up with ways to make Machine Learning even more accessible, and opens up the possibilities for everyone to make the most of it in their apps.</p><h3>Zero to App: Live Coding a Cross-Platform App on Firebase</h3><p>As an iOS and Android developer, I’m always a bit of a sucker for any sessions that focus on cross-platform development. I love being able to see features side by side on both platforms, and it’s a really good way of bringing mobile developers closer together.</p><p>I particularly enjoyed the style of this session, as it was all about collaboration and communication, while also showcasing the best features of Firebase.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2Fgvbq12bGqHI%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3Dgvbq12bGqHI&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2Fgvbq12bGqHI%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/9cd8ae290bba6a398ea6d09384b4f638/href">https://medium.com/media/9cd8ae290bba6a398ea6d09384b4f638/href</a></iframe><h3>ML Kit: Machine Learning for Mobile with Firebase</h3><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FQwHD36bhXZA%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DQwHD36bhXZA&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FQwHD36bhXZA%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/4f14231acdc81b8c342e34c4114fcc9e/href">https://medium.com/media/4f14231acdc81b8c342e34c4114fcc9e/href</a></iframe><p>After watching the session focusing on new features on Firebase, and seeing the updates to MLKit, this ‘ML for Mobile’ session was of particular interest.</p><p>The way this presentation was mixed with live demos and code samples was really interesting and is a very engaging talk.</p><p>Some particular highlights for me were the offline language processing, which was shown to be incredibly fast for translations, and also the collaboration with IKEA, which lets you find matching or similar items in the IKEA catalogue.</p><p>As someone with a creative background, the collaboration with the Material Design team was really exciting. Sometimes more technical features can ignore the user experience for developers, and it’s fantastic to see this being thought about, while also making it easier to make beautiful apps while utilising MLKit.</p><p>Finally, the introduction of custom models is what had initially attracted my attention from the main session. I particularly loved the example of identifying dog breeds!</p><p>The user interface for the AutoML tab, which guides you through creating your own data sets, has really helped me understand more about the data and model that I want, whilst also taking away a lot of the complexity that has blocked me from approaching machine learning in the past. Being able to pick and choose between different sizes and training times makes it feel far more flexible.</p><p>Overall this is probably my favourite talk. I found the presenters were all really clear, and the live demos really helped me understand how I might use these new machine learning features myself.</p><h3>Understand and Engage Your Top Users with Dynamic Audiences</h3><p>Analytics is something that as an app developer, is really important to understand and utilise to the maximum of their potential. Having overall project level analytics is incredibly useful, and as a cross-platform developer, it is invaluable.</p><p><strong>Enhanced filters</strong></p><p>This new feature adds a huge amount of flexibility to understand the data provided by Analytics. The example they gave was whether completing the tutorial in a game meant that you stayed playing the game for longer and gave you better scores. Being able to apply these filters across platforms enables you to understand overall trends that might be less platform specific.</p><p>Being able to utilise Audiences to compare and contrast the data between different groups allows you to really quickly understand any differences. The removal of limitations on what and how many filters you can apply means that you can dive incredibly deeply into your data, which can only help you improve your own apps.</p><p>The particular highlight of this is the ability to make Audiences based on “Observed Behaviour”, which you can then use to target these users using Cloud Messaging, Remote Config and Google Ads. This means you can potentially address any issues or user behaviours immediately without requiring a new app build.</p><p>Furthermore, the Audience Builder interface is fantastically easy to use and is really clear on what data you will be collecting and what events you want to target by including the Summary card that gives visual guides for your data sets. I also loved the recommended analytics events that Firebase thinks you should use depending on your app’s category.</p><p><strong>Analysis</strong></p><p>The announcement of the new feature “Analysis” was really exciting to me. This is accessible through the Analytics dashboard once you’ve linked to Firebase. This gives you incredibly detailed access to your data, including visualisations such as Exploration, Segment Overlap and most interestingly for me, Funnel Analysis.</p><p>The ease of getting started with this immediately from Google Analytics is brilliant, and the UI is immediately easy to understand, which is something I’ve found difficult in the past with data platforms. The visualisation of creating a funnel completely makes sense, and you can get previews of how your data might look, and get immediate feedback on your app with barely any setup. The ability to “View Abandonments” is particularly interesting. It allows you to understand deeply your users who drop out of your defined funnels, which could prove incredibly valuable!</p><p>The period comparison feature within the scatter plot graph was really interesting, and it is so easy to understand the trends in your data and identify and declines before they become serious problems. You can then link this in to the Audiences features to target any issue groups, giving you huge control over your app and your users.</p><p>Analysis rolls out this Summer.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FouZkadjMn94%3Ffeature%3Doembed&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DouZkadjMn94&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FouZkadjMn94%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/c8fe3e21b8a9721e520cf2b76baac18e/href">https://medium.com/media/c8fe3e21b8a9721e520cf2b76baac18e/href</a></iframe><p>I’ve only scratched the surface in this post on the range of topics and things to learn about Firebase from I/O. I’d really recommend watching the talks I’ve highlighted above, and you can find the Firebase at I/O playlist <a href="https://goo.gle/2GSFVqN">here</a> for the rest.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*mMpq8uxDKdmaVzGk" /><figcaption>Attending Google I/O 2018</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d0f6cb58daf8" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Getting Started with Firebase on iOS: Part 3]]></title>
            <link>https://medium.com/@niamhpower/getting-started-with-firebase-on-ios-part-3-c5d693a4c4d7?source=rss-61de4ad69c14------2</link>
            <guid isPermaLink="false">https://medium.com/p/c5d693a4c4d7</guid>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[firebase]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[google]]></category>
            <category><![CDATA[firebase-cloud-functions]]></category>
            <dc:creator><![CDATA[Niamh Power]]></dc:creator>
            <pubDate>Fri, 11 Jan 2019 14:31:00 GMT</pubDate>
            <atom:updated>2019-01-11T14:31:00.762Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*g8OMNiLu_jtyvDnhh3lT9A.png" /></figure><p>This is the third part of the ‘Getting started with Firebase on iOS’ series. We are currently part way through creating an iOS app that mimics the functionality of the Slack app, LunchTrain. <a href="https://medium.com/@niamhpower/getting-started-with-firebase-on-ios-part-2-f1de3621007a"><strong>You can find the second part here.</strong></a></p><p>In the second part, we covered implementing the Train Detail screen, and also did some refactoring. In this part, we will implement notifications and Cloud Functions. Note, you <strong><em>will need an Apple Developer Account</em></strong> to do this section. It will not be vital to finishing the app.</p><p>We will follow this by implementing some database rules to better control what a user can do and see in the app, including not locking the user out of certain functionality by not being able to log in.</p><h3>Notifications</h3><p>Remember, in order to complete this section, you’ll need a paid Apple Developer Account and a <strong>physical iOS device.</strong> Unfortunately this doesn’t work on the simulator ☹️</p><p>To get your account ready and set up your app, you’ll need to first log into the Apple Developer Console. Once there, navigate to the Certificates, Identifiers and Profiles section, and then the Identifiers -&gt; App IDs section, and click the + button to start adding a new ID.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MJnVWh6i23-EooRV4t-uTg.png" /></figure><p>We now need to fill out the following:</p><ul><li><strong>App ID Description</strong> — Just your app’s name.</li><li><strong>Explicit App ID — </strong>This is the id you have in your project file. For example com.yourname.lunchtrain. You should already have this from linking your app to Firebase.</li></ul><p>Then under App Services, tick `Push Notifications.` Press <strong>continue</strong>.</p><p>Now confirm the details you entered are correct, and press <strong>Register.</strong></p><p>Now we want to edit the details of the App ID you just created, so select this, and click the <strong>Edit</strong> button. Scroll down to the Push Notifications section, and select <strong>Create Certificate.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7EHPT3eLPYqhvSqpBWYWbw.png" /></figure><p>The console will then guide you through generating this certificate. Follow this through and download the final result.</p><p>Now you have the certificate, find it in the Finder, and double click to add it to your keychain. Next, open up <strong>Keychain Access </strong>application, and find the certificate. It should be under the <strong>My Certificates</strong> category.</p><p>Once you have found it, click the arrow on the left to expand it, and right click on the private key and select <strong>Export</strong> and save it to a convenient location.</p><p>We’re now done with all the developer console faff! yay! Now we can move back to the <strong>Firebase Console</strong> to get the set up completed 😅</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*9D0dwO3zhSqGF73x_p8anQ.png" /></figure><p>Go to the project settings for your app in the Firebase Console. Select the <strong>Cloud Messaging</strong> tab at the top, and scroll down to the iOS App Configuration section. Click the upload certificate button in the <strong>Development</strong> section, and navigate and upload the certificate we saved in a convenient location earlier.</p><p>Remember, if you want to release your app in the App Store, you will need to create a production certificate and set up the console accordingly. In this tutorial, we are going to stick to the development setup.</p><p>Now all the config is complete, we can move back to writing some code and getting it running on a device! 🚀</p><p>Another pod! This time, we want the <strong>Messaging</strong> CocoaPod, like so:</p><pre>pod &#39;Firebase/Messaging&#39;</pre><p>Now head over to the project file, and navigate to your target, and select the <strong>Capabilities</strong> tab. In this menu, turn on the <strong>Push Notifications</strong> switch.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CvYxt4qhtodTkKYMGXqISw.png" /></figure><p>Now we want to update the AppDelegate. Implement the below changes:</p><p>Now we’re all set! Run the app to get your device registered and ensure that everything builds properly. We can now send a test notification to check it all works.</p><p>From the Firebase console, navigate to the <strong>Cloud Messaging </strong>section, and select the option to <strong>Send your first message</strong>. Fill out all the relevant details, and hit send! Your test notification should now appear on the device you ran the app on. Remember, <em>this only works on real devices, not the simulator.</em></p><h3>Cloud Functions ☁️</h3><p>Now we have push notifications set up, we want to work out when we want to send these notifications. We can do this using Firebase’s <strong>Cloud Functions</strong>. These are basically small snippets of Node.JS code that sit on a server and can be triggered by a variety of conditions. Handily, one of these conditions can be when data changes in the Firestore!</p><p>We need to get the environment set up first though, which requires us having the Node package manager installed on your terminal. This is a great guide for installing Node.js and the package manager using Homebrew: <a href="https://changelog.com/posts/install-node-js-with-homebrew-on-os-x">https://changelog.com/posts/install-node-js-with-homebrew-on-os-x</a></p><p>Once you’ve done this, navigate your terminal to your app folder, and run the command:</p><pre>npm install -g firebase-tools</pre><p>This installs all the available tools to use Firebase on the terminal globally, so you can access from any folder.</p><p>Next, run firebase login and sign in to the account you have your app registered under.</p><p>Now you can run firebase init functions and follow the guide that is provided. Once this is set up you should find that a functions folder has been created in the directory, and a firebase.json file. Open up the index.js file from the functions folder in an editor of your choice.</p><p>First, add this code to the top of the file:</p><pre>// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.</pre><pre>const functions = require(&#39;firebase-functions&#39;);</pre><pre>// The Firebase Admin SDK to access the Firebase Realtime Database.</pre><pre>const admin = require(&#39;firebase-admin&#39;);</pre><pre>admin.initializeApp();</pre><p>You should find an example function ready commented out. Uncomment this, save the file, and then run the command:</p><pre>firebase deploy --only functions</pre><p>Once this has completed successfully, you should be able to see your function in the <strong>Cloud Functions</strong> section of the Firebase Console.</p><h4>Triggering Functions</h4><p>Now we have Cloud Functions all set up and our environment ready, we can start creating the function that will observe our Firestore.</p><p>The below function simply watches for any new trains being created. Currently it doesn’t do anything when this happens, it just gets the name value from the new Train. However, we can use this to test that our set up is working.</p><pre>exports.newTrain = functions.firestore.document(&#39;trains/{title}&#39;).onCreate((snap, context) =&gt; {</pre><pre>const newValue = snap.data;</pre><pre>const name = newValue.name.toString();</pre><pre>});</pre><p>Once you’ve added this function to your index.js file, run your app and test out adding a new Train. You should be able to see in the Firebase Console the latest call of the function.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AXMbueSaX-R5ek0ka3YDDw.png" /></figure><p>We’re getting an error here as we haven’t actually returned anything in our function, however we can see that the event has linked up correctly! 🙌🏻 You’ll also notice an error due to not adding a billing account — this is fine for now in development, but will be needed to be added should you start sending more requests.</p><p>Now we actually want to handle this event, and send off our notification when this happens.</p><h4>Sending our notification</h4><p>When we start to think about being able to send notifications to registered devices, we come across a bit of a problem: We don’t know the devices registered! One solution to this is to subscribe each device to a <strong>Topic</strong>. We can then send notifications to any device subscribed, rather than having to get a list of devices from Firebase. This also makes it much easier if we ever want to implement a settings page where users can subscribe and unsubscribe to certain notifications.</p><p>This is the best solution for when a new train is created, if we want to send a notification to a train owner when someone joins for example, a directed notification to their device token would be more suitable, and when sending a notification about the train leaving, device group messaging would be best. Handily, we have a use case for the three different types, so we will cover all of these in this section.</p><p><strong>Topic Messaging</strong></p><p>In order to create a topic for devices to subscribe to, we simply need to call the subscribe function and the server will create the topic automatically if it doesn’t already exist.</p><p>In the AppDelegate within the didReceiveRegistrationToken method, add the code:</p><pre>func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {</pre><pre>...<br>  Messaging.messaging().subscribe(toTopic: &quot;newTrains&quot;)<br>}</pre><p>Now run the app, and the topic newTrains will have been created, and we can use it within our function.</p><p>Add the extra code to the newTrain function, which creates the payload and options for the notification, and handles sending this to the newTrains topic.</p><p>Make sure to deploy the new index.js file!</p><p>Now we can test that this works by creating a new train from our device, and see whether we receive a notification. We should also see it logged out in the console as before, and see the relevant notification sent in the <strong>Firebase Messaging </strong>section.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sDpFM_E47kRKF4syhEeJ2Q.png" /></figure><h4>New Passengers</h4><p>Here we want to do some refactoring to actually link users to a train, and to do this we actually need to store our Users when they sign up. To do this we want to make the model in our code, and start linking up.</p><pre>struct User: Codable {<br>  var userId: String?<br>  var userName: String<br>  var deviceToken: String? = &quot;&quot;<br>}</pre><p>You’ll notice we’ve now got this Codable within the struct declaration, this allows us to skip the pesky dictionary declaration.</p><p>In order to use this with the Firestore, we can use this great library, called Codable Firebase</p><p><a href="https://github.com/alickbass/CodableFirebase">alickbass/CodableFirebase</a></p><p>Then when we want to encode a new User to send to our Firestore, we can simply call this:</p><pre>let newUser = try! FirestoreEncoder().encode(User(userId: userId, userName: userName, deviceToken: deviceToken))</pre><pre>...</pre><pre>transaction.setData(newUser, forDocument: newUserReference)</pre><p>And the same for decoding the data when we receive it:</p><pre>do {<br>  let model = try FirestoreDecoder().decode(User.self, from: document.data())<br>  return model<br>} catch {<br>  print(&quot;error parsing document: \(document.data())&quot;)<br>  return nil<br>}</pre><p>Now we want to be able to set up the user when they sign in, store their details along with their device token that gets set when they register for notifications. Handily, only once a user gives permission will we have this value, so we won’t be wasting time sending notifications to people who said no anyway!</p><p>First, we want to get the device token. We can do this by adding this method to the AppDelegate:</p><pre>func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)  {<br>  if let refreshedToken = InstanceID.instanceID().token() {<br>    let defaults = UserDefaults.standard<br>    defaults.set(refreshedToken, forKey: Keys.deviceToken.rawValue)<br>  }<br>}</pre><p>Here we’re just saving the device token to the UserDefaults, ready to use later once the user has signed in.</p><p>Then, in our BaseViewController, we can add the call to get this device token, and save our new user:</p><pre>func authUI(_ authUI: FUIAuth, didSignInWith authDataResult: AuthDataResult?, error: Error?) {<br>  let deviceToken = UserDefaults.standard.string(forKey: Keys.deviceToken.rawValue)</pre><pre>TrainService().saveNewUser(deviceToken: deviceToken, callback: nil)</pre><pre>showList()</pre><pre>}</pre><p>Notice we have the device token as optional in both the User object, and the saveNewUser function.</p><p>Now we have our Users, we can attach a user id to the passenger collection, which then allows us to have a reference to everyone interested, and send notifications to a set of devices.</p><p>In the next part, we will dig into the Database Rules we can use with the Firestore, and implement proper grouping and privacy for our trains.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c5d693a4c4d7" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The great migration. Moving from Fabric to Firebase as an iOS developer.]]></title>
            <link>https://medium.com/@niamhpower/the-great-migration-moving-from-fabric-to-firebase-as-an-ios-developer-7b61a8b40008?source=rss-61de4ad69c14------2</link>
            <guid isPermaLink="false">https://medium.com/p/7b61a8b40008</guid>
            <category><![CDATA[google]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[fabric]]></category>
            <category><![CDATA[firebase]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Niamh Power]]></dc:creator>
            <pubDate>Tue, 08 Jan 2019 17:07:15 GMT</pubDate>
            <atom:updated>2019-01-10T13:00:02.000Z</atom:updated>
            <content:encoded><![CDATA[<p>In my day to day work and speaking at meet-ups, I am always surprised by how little most iOS developers know about Firebase, and the range of tools it has on offer for all developers. Being a Google technology this is understandable, but if you’re interested to learn more about what you can do with Firebase as an iOS developer then check out my blog series <a href="https://medium.com/@niamhpower/getting-started-with-firebase-on-ios-part-1-612af4bcabd6">here</a>.</p><p>For now, though, this post is going to focus on what you need to do to migrate your Crashlytics instance across from Fabric to Firebase.</p><p>I’m going to be using one of my more basic projects on GitHub to run this through, so feel free to post any questions if I miss anything that might be the case in more complex projects.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YTYSLOCQEA6VsrjiVRuANw.png" /></figure><p>First off, if you use Fabric often, you’ll probably have noticed this header pop up in your dashboard. If you click on the Get Started button, you’ll be redirected to a handy migration assistant.</p><p>Now you might be asking, why make this blog post if Firebase has already made an assistant? Good question, but the aim of this post is to show you how easy it is to migrate even large repositories, and that it’s something you should be doing now rather than just before the upcoming deadline.</p><p>First off, you’ll be prompted to log in with your Google account. If it’s a personal project you can use your normal one, however, if you’re doing this for your company’s app it’s worth checking to see what your Android team-mates use for Firebase, or if there is a general Google account you can use for this.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GwbaoqTmS5nWVVHxcRpdaA.png" /></figure><h3>Link your apps to Firebase</h3><p>Before we can even start using Crashlytics within Firebase, we need to actually create the app in the Firebase console.</p><p>Once you click through to link your app, you’ll be greeted by a super handy dashboard.</p><p>Then you simply need to drag the app you want to link, over to the box on the right:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*19HHL7UsgCAD_c7CbQzSmw.png" /></figure><p>You’ll then be given a dialog where you can fill out the relevant information for your new Firebase app. You are then given the choice of whether to share your anonymous data with Google, of course, your choice!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*W2JE6Lxrz-WcWybuZrVNBA.png" /></figure><p>You’ll then see a big button across the bottom of your screen to complete the link between the apps. If you logged into the Firebase console you would now see the app you just created, however it won’t have the link yet.</p><p>Hit that button, and confirm. You can now invite your team mates to your new Firebase app, and directly go to your new console and see what you’ve got set up already!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KgLl9d3Dx2MeX9auV3jVzQ.png" /></figure><p>Now when you go back to the migration page, you’ll see your new Firebase app.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/776/1*o-7TvptmU-WhJZQ-fmH90A.png" /></figure><h3>Adding Crashlytics</h3><p>Now we have our new Firebase app set up, we can start to link up Crashlytics too.</p><p>To do this, you’ll want to head over to your app’s Firebase console. Once there, you’ll notice a little red dot over your new app, this is prompting you to finish the SDK set up so we can start using the full feature set of Firebase.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/668/1*IFdECTmqbKAB6DmBRpyL5w.png" /></figure><p>When you continue through this, all the app details such as the Bundle ID, are already populated from Fabric. Now we have to download the GoogleService-Info.plist file and add it to our project.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*56xnQk9HxlSHJMajTMb1UA.png" /></figure><p>Next, you’ll want to add the Firebase/Core pod to your Podfile :</p><pre>pod &#39;Firebase/Core&#39;</pre><p>Save the file and run:</p><pre>pod install</pre><p>Now we can add the initialisation code to our AppDelegate. This works in a similar way to the Crashlytics set up:</p><pre>import UIKit<br><strong>import Firebase</strong><br><br>@UIApplicationMain<br>class AppDelegate: UIResponder, UIApplicationDelegate {<br><br>  var window: UIWindow?<br><br>  func application(_ application: UIApplication,<br>    didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?)<br>    -&gt; Bool {<br>    <strong>FirebaseApp.configure()</strong><br>    return true<br>  }<br>}</pre><p>Now run your app, and it should link up with Firebase automatically.</p><p>And that’s it! You’re up and running with Firebase, and Crashlytics should have automatically been turned on.</p><p>Head to the Quality section, and hit Crashlytics. You should reach a dashboard giving you all the information you need</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WO0wF0SnAFWm_KDmY3er7g.png" /></figure><p>Have fun exploring all the features on offer from Firebase, and feel free to message me should you have any questions.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7b61a8b40008" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Getting started with Firebase on iOS: Part 2]]></title>
            <link>https://medium.com/@niamhpower/getting-started-with-firebase-on-ios-part-2-f1de3621007a?source=rss-61de4ad69c14------2</link>
            <guid isPermaLink="false">https://medium.com/p/f1de3621007a</guid>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[tutorial]]></category>
            <category><![CDATA[google]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[firebase]]></category>
            <dc:creator><![CDATA[Niamh Power]]></dc:creator>
            <pubDate>Thu, 21 Jun 2018 17:13:05 GMT</pubDate>
            <atom:updated>2018-06-21T21:02:46.984Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-G68a5WBePHLaQJvO43JkA.png" /></figure><p>This is the second part of the ‘Getting started with Firebase on iOS’ series. We are currently part way through creating an iOS app that mimics the functionality of the Slack app, LunchTrain. <a href="https://medium.com/@niamhpower/getting-started-with-firebase-on-ios-part-1-612af4bcabd6"><strong>You can find the first part here.</strong></a></p><p>In the first part, we covered authentication and basic Firestore setup. In this part, we will first start with some refactoring and testing of the existing codebase. Then we will implement the Train Details screen, with the ability to see passengers, and also join a train yourself!</p><h4>Refactoring</h4><p>Currently, we have used a fairly basic MVVM architecture. This works well for this small scale project, though we have some points to improve.</p><p>Firstly, the table view in the train list access the view data, within the view model. This could be greatly improved by separating off the table view delegate methods into their own adapter class, allowing for as much business logic as possible to be outside of the View Controller.</p><p>Furthermore, given we are likely to use table views in other areas of the app, such as the passenger list, it is worth us using generics to design a adapter that can be reused.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c08475230d448cbc79605ac62fbc1c3f/href">https://medium.com/media/c08475230d448cbc79605ac62fbc1c3f/href</a></iframe><p>This is the one we will use in the lunch train app. You can build on this to provide more of the delegate methods, depending on your requirements, but for now this implementation is enough for us.</p><p>In order to use this in the app, we need to adjust the view controller as below:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/67318eeb4ae1d9edbd9a885398e03712/href">https://medium.com/media/67318eeb4ae1d9edbd9a885398e03712/href</a></iframe><p>Again, the block within the didSelectItem section doesn’t need to be implemented yet. We will be covering that in the next section. I will do other small refactors as we go 😊</p><h4>Create a Train</h4><p>Now we’re going to move onto adding new Trains from the app. For this, we will need to use some different methods for the Firestore, and implement a new UI.</p><p>We will start with the UI and structure first.</p><p>Create a NewTrain folder, and add theNewTrainViewController.swift and NewTrainViewModel.swift files. We don’t need view data here as we can just reuse the Train model.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/914dbe4fc437916c342d5f7dc53902f0/href">https://medium.com/media/914dbe4fc437916c342d5f7dc53902f0/href</a></iframe><p>You will note that I have added an option to handle an error when creating a new train. We will be looking at error cases and adding UI for these in a later post! For now, to the user, it will not crash but simply dismiss the screen:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e3d6c0dd5b162e122e146e44ccf78116/href">https://medium.com/media/e3d6c0dd5b162e122e146e44ccf78116/href</a></iframe><p>Next, we want to hook this up to the button we have in the list view. This is fairly simple:</p><pre>@objc func addPressed(sender:UITapGestureRecognizer) {</pre><pre>    performSegue(withIdentifier: &quot;addTrain&quot;, sender: self)</pre><pre>}</pre><pre>override func prepare(for segue: UIStoryboardSegue, sender: Any?) {</pre><pre>    super.prepare(for: segue, sender: sender)</pre><pre>    guard let viewController = segue.destination as?   NewTrainViewController else { return }</pre><pre>    viewController.viewModel = NewTrainViewModel()</pre><pre>}</pre><p>As you can see, we now have a dedicated screen for entering the train details, which automatically gets the user’s name and creates a new Train. If you open the Firebase console while creating this, you should see the collection automatically update, and the list will update with the new Train when you return to it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/350/1*ki1vVUwJgWsWf5kAa-40ng.png" /></figure><h4>Viewing Trains</h4><p>Now we want the user to be able to select a train, and see the relevant details. For this again, create a new group, named TrainDetails and add the files TrainDetailsViewController.swift TrainDetailsViewModel.swift and TrainDetailsViewData.swift</p><p>In the view data, we will have a reference to the Train and also the DocumentReference for the chosen train, in order to perform operations later.</p><p>Then in the view model for now, it will only contain the didChangeData block, as we don’t need to do any network calls or data manipulation for now.</p><p>Again, feel free to customise your UI as you see fit. I have included a table view and a button ready for the passenger list and the ability to join a train.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fd0e5cd2b372ed9596321e085a443749/href">https://medium.com/media/fd0e5cd2b372ed9596321e085a443749/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f0adfbaa7bd62597c7923e2b84cd5d74/href">https://medium.com/media/f0adfbaa7bd62597c7923e2b84cd5d74/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/61d033dd30482a4d013183b57ecdcfa3/href">https://medium.com/media/61d033dd30482a4d013183b57ecdcfa3/href</a></iframe><p>So at this point, we have the ability to see the trains, and click into them to view more details. The join train button doesn’t currently work, so the passengers list isn’t functional at this point.</p><p>In order to implement this list, and the button, we want to add similar functionality to how we handled the list of trains, but just listen to a different collection of documents.</p><p>First off, we want to create a new data class to represent a user. This is really similar to the Train model we made earlier.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4e43db2b244bde775803b61c5f71d829/href">https://medium.com/media/4e43db2b244bde775803b61c5f71d829/href</a></iframe><p>For now, these users are going to be made per train. Later on we can look at improving this, so a user can see all the trains they have joined, and manage their trains more effectively.</p><p>Add the methods to the TrainDetailViewModel as shown below, to observe the passengers collection within the Train model.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a07faffb329381f222520bcdfa216355/href">https://medium.com/media/a07faffb329381f222520bcdfa216355/href</a></iframe><p>Next, just add the viewModel calls into the view lifecycle methods, to ensure no observers are left over when you leave the screen.</p><pre>override func viewWillAppear(_ animated: Bool) {</pre><pre>  super.viewWillAppear(animated)</pre><pre>  viewModel.observeQuery()</pre><pre>}</pre><pre>override func viewWillDisappear(_ animated: Bool) {</pre><pre>  super.viewWillDisappear(animated)</pre><pre>  viewModel.stopObserving()</pre><pre>}</pre><pre>deinit {</pre><pre>  viewModel.stopObserving()</pre><pre>}</pre><p>Now you should be able to run the app, but nothing will happen! This is because there’s not actually any data in your passengers collection yet, and there probably won’t be that value in the database either! So first we need to initialise each train with the list of passengers with just the owner inside.</p><p>Head over to your Firebase console, and delete all the trains you have in their, or add a passengers field to each, otherwise we’re going to have issues later! Our guard statements keep us pretty safe, but in order to keep our database clean it’s a good idea to reset here, while we’re in active development.</p><p>If you choose to add to existing Trains, make sure you click Add Collection rather than the Add Field, as this then creates a new collection inside the train document. Your console should then look similar to below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AAFHmqfhYdEbVTaNUU1QEg.png" /></figure><p>Last, but definitely not least, we want to give our table view the data we get! Again, we’ll do this in the same way as in the list, with a table view adapter to handle the data. Handily, we made a generic adapter in our first part, so we can simply reuse this! Just make the below changes to the TrainDetailViewController :</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e9e981a793f6dd464b13c784c3335302/href">https://medium.com/media/e9e981a793f6dd464b13c784c3335302/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/350/1*bD6TIBHAlC6D_bj9DeIcZA.png" /></figure><p>You’ll note that we have made a cell view this time, for now this is fine, as we only have the name field to show. We will customise this more in future parts 🎉</p><p>Now when you load up your app, if you’ve added a train with passengers, you should be able to click on this and see the list in the detail view.</p><p>If you haven’t yet, try adding some data into your trains, and see what happens. Does the app crash if the data isn’t the right type?</p><h3>Joining a Train</h3><p>The last main functionality we’re going to add in this part is the ability for a user to join a train. For this, we want to add a gesture recogniser to our button, and handle the tap. When this happens, we want to get the user’s name, and simply create a User, which can then be added to the passengers collection. This should then automatically update the table view in the details.</p><p>In terms of UX, we probably want to add an activity indicator to replace the button whilst this is handled. And also the option to grey out the button if the user is already in the train. We’ll be adding the ability to leave a train later (again 🙃)!</p><p>First, add this code to our setup method:</p><pre>let gesture = UITapGestureRecognizer(target: self, action: #selector(self.joinPressed))</pre><pre>joinTrainButtonView.addGestureRecognizer(gesture)</pre><p>Then we want to create the joinPressed method:</p><pre>@objc func joinPressed(sender: UITapGestureRecognizer) {</pre><pre>  //call a method on the view model!</pre><pre>}</pre><p>Now this is all tied up, we can implement the method on the viewModel. Add a public method joinTrain as below:</p><pre>fileprivate func baseQuery() -&gt; CollectionReference? {</pre><pre>  return trainReference?.collection(&quot;passengers&quot;)</pre><pre>}</pre><pre>func joinTrain() {</pre><pre>  guard let query = query else { return }</pre><pre>  let user = Auth.auth().currentUser</pre><pre>  let name = user?.displayName ?? &quot;&quot;</pre><pre>  let passenger = User(name: name)</pre><pre>  let newPassengerReference = query.document()</pre><pre>  Firestore.firestore().runTransaction( { (transaction, errorPointer) -&gt; Any in</pre><pre>    transaction.setData(passenger.dictionary, forDocument: newPassengerReference)</pre><pre>}) { [weak self] (object, error) in</pre><pre>  guard let strongSelf = self else { return }</pre><pre>  if let error = error {</pre><pre>    print(error)</pre><pre>    strongSelf.joinTrainRequestCompleted?(false)</pre><pre>    return</pre><pre>  }</pre><pre>    strongSelf.joinTrainRequestCompleted?(true)<br>  }</pre><pre>}</pre><p>You’ll note I’ve change the baseQuery method to return a CollectionReference to allow use to more easily create new documents. You’ll need to change the baseQuery type to CollectionReference too.</p><p>You’ll also notice that I’ve added a new callback, joinTrainRequestCompleted . We can use this to handle stopping the activity indicator, and display an error if needed.</p><p>In your bindViewModel method, add this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3ccde9c77dc487c4ddc35e226493ef6d/href">https://medium.com/media/3ccde9c77dc487c4ddc35e226493ef6d/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/333/1*C6SyV-1Sf3iu4-nlEU5trA.gif" /></figure><p>Once you implement the new code for the detail view controller, you should get a similar result as the GIF on the left. Feel free to customise this as you wish.</p><p>You’ll notice that once we’ve joined a train, leave the view, and then return, the join train button is available again. In order to handle this, we need to cross check the list of passengers against the current user. Again, this will be simpler once we know which lunches a person is involved with, but for now this will work.</p><p>Add the following code to your view model. Here we are getting the current user’s name, and doing a simple check within the passengers list.</p><pre>private func checkIfUserIsAPassenger() {</pre><pre>  viewData.isUserAPassenger =   viewData.passengers.contains(User(name: getCurrentUserName()))</pre><pre>}</pre><pre>private func getCurrentUserName() -&gt; String {</pre><pre>  let user = Auth.auth().currentUser</pre><pre>  return user?.displayName ?? &quot;&quot; </pre><pre>}</pre><p>Add a isUserAPassenger boolean field defaulting to false on the TripDetailViewData struct. This allows us to simply check this value in the view controller, rather than having more complex callbacks or logic to deal with.</p><p>You’ll notice at this point that we will have build errors. This is because the compiler doesn’t know how to compare different User objects. For this, we need to make User conform to the Equatable protocol.</p><p>Add this extension to your struct:</p><pre>extension User: Equatable {</pre><pre>  static func ==(lhs: User, rhs: User) -&gt; Bool {</pre><pre>    return lhs.name == rhs.name</pre><pre>  }</pre><pre>}</pre><p>Finally, we want to trigger this check. It makes the most sense to check this any time the data is updated, so within the didSet of the viewData.</p><pre>var viewData: TrainDetailViewData {</pre><pre>didSet {<br>    checkIfUserIsAPassenger()</pre><pre>  }</pre><pre>}</pre><p>Because we want to update the view data after this check, we can move the didChangeData?(viewData) call to within the check method. Simply add the call to the checkUserIsPassenger() function.</p><p>Now we want to handle this. Within the didChangeData block in the TrainDetailViewController , add the code to grey out the button if the value is true.</p><pre>if data.isUserAPassenger {</pre><pre>  strongSelf.disableButton()</pre><pre>}</pre><p>The disableButton method contains the code we wrote earlier:</p><pre>private func disableButton() {</pre><pre>  joinTrainButtonView.backgroundColor = UIColor.gray</pre><pre>  joinTrainButtonView.isUserInteractionEnabled = false</pre><pre>}</pre><p>Now we just need to call the check in the viewModel! Just add the function call within the response from the firestore, as shown:</p><pre>self.viewData.passengers = models</pre><pre>self.checkIfUserIsAPassenger()</pre><pre>self.documents = snapshot.documents</pre><p>This means anytime the data is updated, we will be checking the value. There are likely more efficient ways of doing this. Can you think of any? Perhaps within the mapping of the response from Firebase?</p><p>Now we have the main functionality of the app in place, we are in a good position to start implementing more than the MVP. In the next part, we will go through how to implement notifications, and for a user to be able to manage the trains they’ve joined. We ill also look into some database rules, to ensure that a user can’t join a train twice, for example.</p><p>Let me know any questions you may have in the comments, and as always feel free to ping me on Twitter!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f1de3621007a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Getting started with Firebase on iOS: Part 1]]></title>
            <link>https://medium.com/@niamhpower/getting-started-with-firebase-on-ios-part-1-612af4bcabd6?source=rss-61de4ad69c14------2</link>
            <guid isPermaLink="false">https://medium.com/p/612af4bcabd6</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[tutorial]]></category>
            <category><![CDATA[firebase]]></category>
            <category><![CDATA[google]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Niamh Power]]></dc:creator>
            <pubDate>Fri, 08 Jun 2018 17:01:01 GMT</pubDate>
            <atom:updated>2018-06-21T17:24:13.969Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-G68a5WBePHLaQJvO43JkA.png" /></figure><p>In this blog post series, I’m going to take us through making a full iOS application, using Firebase. We’ll be making a Lunch Train app, which mimics the functionality of the Slack application. This tutorial is aimed at those fairly new to iOS development, and having never used Firebase before. However I would hope those who are experienced in either can find this useful.</p><p>The main features are:</p><ul><li>A user can create a “Lunch Train”, choosing a place and a time</li><li>A user can join a “Lunch Train”</li><li>A user can see the passengers of the “Lunch Train”</li><li>A user can be notified when people join their train</li><li>A user can be notified when the train is leaving</li></ul><p>Throughout this post, I will be using the term “train” to refer to a “Lunch Train”.</p><p>In this part, we will get the user authenticated, and setup the Cloud Firestore to have references to different trains.</p><h3><strong>Set up Firebase</strong></h3><p>Go to <a href="https://console.firebase.google.com/">the Firebase console</a>, and log in with your Google account. You should be presented with the Firebase welcome screen, click the ‘Add Project’ button.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mQNI_Bun_qzPXppGBm-VZA.png" /><figcaption>Project creation dialog</figcaption></figure><p>Fill in the relevant details for your app, this can be anything as you can edit it later. Once the setup is complete, you will be in the Firebase console.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*61F-1YNpC3-Uh0vWgsAiFg.png" /><figcaption>Firebase Console</figcaption></figure><p>Select the ‘Add Firebase to your iOS app’ button. This is the step where we now want to know a couple of details from our application. Switch over to Xcode.</p><p>Create a new single view app in Xcode, with any name you want. The organisation name and identifier form the first part of the bundle ID, and this value is what you will be entering into the Firebase console.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*poe_1GR5gPFic1NThvu12w.png" /><figcaption>Xcode Project information</figcaption></figure><p>You should now be presented with the project information screen, take a copy of the ‘Bundle Identifier’. Now go back to your Firebase console, and enter it into the first field of the dialog.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/814/1*gRinO00Kb-7DxLSHKiyViw.png" /><figcaption>Firebase create iOS project dialog — bundle ID field</figcaption></figure><p>Next up, Firebase will provide a GoogleService-Info.plist for you to download. Follow the instructions here and insert it into your project.</p><p><strong>Firebase Cocoapod</strong></p><p>Firebase is provided as a CocoaPod — make sure <a href="https://guides.cocoapods.org/using/getting-started.html">you have this installed</a> before progressing to the next step.</p><p>From the terminal, navigate to where you have created your project, and initialise the pod spec.</p><p>cd Documents/Firebase\ Project</p><p>pod init</p><p>Now open the Podfile. You can do this by simply running open Podfile from the terminal.</p><blockquote># Uncomment the next line to define a global platform for your project<br># platform :ios, ‘9.0’</blockquote><blockquote>target ‘Firebase Project’ do<br> # Comment the next line if you’re not using Swift and don’t want to use dynamic frameworks<br> use_frameworks!</blockquote><blockquote># Pods for Firebase Project</blockquote><blockquote>target ‘Firebase ProjectTests’ do<br> inherit! :search_paths<br> # Pods for testing<br> end</blockquote><blockquote>end</blockquote><p>Add the line:</p><p>pod Firebase/Core</p><p>Make sure you save! Then back in the terminal, run pod install. This will go through your Podfile and install any missing dependencies. Once this is complete, close Xcode, and open the newly generated .xcworkspace file. You should see the Pods project within the Xcode project navigator now.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/630/1*Q8yEDFsCcfr3C6EjrpPS-w.png" /><figcaption>User analytics view in the Firebase Console</figcaption></figure><p>Click to the next step in the Firebase dialog, and the code provided to insert into the AppDelegate is provided. Simply import the Pod, and add the configure line.</p><p>Once this is complete, when you run the app, it will link up to your Firebase account. You should be able to see the active users value is now at one under the Analytics option.</p><h3>Authentication</h3><p>Now we have our app linked to Firebase and our project, we can start the development of our Lunch Train app. We will want a way of identifying users, and for users to be able to have trains associated to them, therefore having a form of authentication makes sense.</p><p>Luckily for us, Firebase provides a platform for this. In the console, select “Authentication” in the sidebar menu.</p><p>We then want to set up some sign in methods. Firebase offers a range of options for this. However for this project we will just stick to Google &amp; email sign ins for simplicity. Simply click through on the Set up sign up method and enable to two options.</p><h4>Add Authentication to the app</h4><p>In order to use Firebase authentication, we can use the pre-made authentication flow, which provides some basic UI and handles the calls for us.</p><p>We’ll need two more pods for this:</p><p>pod ‘FirebaseUI/Auth&#39;</p><p>pod &#39;FirebaseUI/Google&#39;</p><p>Then we want to import these into our ViewController.swift class:</p><p>import FirebaseAuthUI</p><p>import FirebaseGoogleAuthUI</p><p>This allows us to then launch the authentication on start up. Add the viewDidAppear override method to your code, and show the authentication flow if needed:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/eb669657ed362c0492be3816eef3cc5a/href">https://medium.com/media/eb669657ed362c0492be3816eef3cc5a/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/350/1*TAGM2HoMGfGYgXT7S3cMnw.png" /></figure><p>We also need our ViewController to conform to the Auth delegate.</p><p>class ViewController: UIViewController, FUIAuthDelegate {</p><p>and then implement the auth UI method:</p><pre>func authUI(_ authUI: FUIAuth, didSignInWith user: User?, error: Error?) {</pre><pre>  // Handle user returning from authenticating<br>}</pre><p>Once you’ve signed in, you will be able to open the Firebase console, and see that user account in the authentication section.</p><h3>Showing some data</h3><p>Now we have users and a way to authenticate them, we can start to use the <a href="https://firebase.google.com/docs/firestore/">Cloud Firestore</a>. Navigate to the database section in the console, and enable the Cloud Firestore. We will start off in “Test Mode”, which allows reading and writing data without authentication. We will dig more into database rules in a future post.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mfwd_dk7jkhd_RdiXTOyYg.png" /></figure><p>Create a trains collection, and add a few test documents. Select auto-ID and create the owner place time and title fields. Make sure the time field is a timestamp type, all the rest can be string .</p><p>Now we have a sample set of data set up, we want to be able to view this in the app. First, add the Firestore pod to the project:</p><p>pod &#39;Firebase/Firestore&#39;</p><p>Create a TrainList group within the project, and create the classesTrainListViewController.swift TrainListViewModel.swift and TrainListViewData.swift</p><p>We’ll start at the data layer. We want to create a Train data model to map from the data from the Firestore, and we want a way to reference the list of trains shown in the app.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f7d12b7fc1035f0e6f8f76f354823382/href">https://medium.com/media/f7d12b7fc1035f0e6f8f76f354823382/href</a></iframe><p>Now we want to use this data, in the view model layer, which is where our business logic for retrieving from the Firestore, and handling the data sits.</p><p>For initialising our view controllers with a view model, I used the technique detailed in this blog post <a href="https://medium.com/@shanev/view-model-specialized-view-controllers-using-storyboards-in-swift-88169d2b43c7">https://medium.com/@shanev/view-model-specialized-view-controllers-using-storyboards-in-swift-88169d2b43c7</a></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4ef095e14f2578d75122d4b42b233f1e/href">https://medium.com/media/4ef095e14f2578d75122d4b42b233f1e/href</a></iframe><p>Finally, we want to create our view controller, with a table view to show the trains in the database:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b1f7107ae635e5f6da49212dae314ff3/href">https://medium.com/media/b1f7107ae635e5f6da49212dae314ff3/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/350/1*a0Y_dZz1IKpTbM5HXAThaA.png" /></figure><p>You can customise how the cells are shown if you wish. With a basic implementation you should get something similar to the screenshot here.</p><p>I have also added a ‘Create Train’ button here, but this isn’t required yet, and I will cover this in more detail in the next post.</p><p>What you should notice now, is that if you have the app open, and add or delete items in your Firestore, it should be reflected in your app immediately, thanks to the listeners added in the view model.</p><p>To note, if there are parts that you wish to see more of and dig into the code, you can find the full repository here:</p><p><a href="https://github.com/niamh-power/lunch-train">niamh-power/lunch-train</a></p><p>Note this is a more complete version than we have currently at this stage in the series, though you should still find everything you need.</p><p>In the next post, we will be looking at some refactoring that we can do to the current code, as well as adding the option to create a train, and join any existing ones. <a href="https://medium.com/@niamhpower/getting-started-with-firebase-on-ios-part-2-f1de3621007a"><strong>You can find that next post here!</strong></a></p><p>Feel free to comment below or message me on <a href="http://twitter.com/niamh__power">Twitter</a> if you have any questions or thoughts!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=612af4bcabd6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Banishing Burnout]]></title>
            <link>https://medium.com/@niamhpower/banishing-burnout-e24d4ed5135?source=rss-61de4ad69c14------2</link>
            <guid isPermaLink="false">https://medium.com/p/e24d4ed5135</guid>
            <category><![CDATA[mental-health]]></category>
            <category><![CDATA[work]]></category>
            <category><![CDATA[development]]></category>
            <category><![CDATA[self-improvement]]></category>
            <category><![CDATA[software-development]]></category>
            <dc:creator><![CDATA[Niamh Power]]></dc:creator>
            <pubDate>Sun, 01 Apr 2018 12:39:14 GMT</pubDate>
            <atom:updated>2018-04-01T12:39:14.513Z</atom:updated>
            <content:encoded><![CDATA[<p>In this blog post, I’m going to discuss how you can best tackle burnout as both an employee and employer. I will touch upon how Novoda approaches these challenges, my own personal experiences, as well as advice from members of the developer community. I hope these thoughts can help you if you are struggling; feel free to reach out to me on Twitter if you need any advice.</p><p>This is a re-blog of my post on the <a href="https://blog.novoda.com/banishing-burnout/">Novoda blog</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/288/1*Kam2-Ki8pKKO6Vei56q8ag.gif" /></figure><p>Last November, Novoda hosted their first annual ‘un-conference’ in Lisbon, Portugal. The idea of an un-conference is that potential speakers can submit a topic and attendees vote on what they want to hear about on the day. The three formats available were talk, workshop, or discussion. One of the key themes of the day that emerged was mental health in the workplace.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9L5uis1tjNDHSdXOd3qNeQ.jpeg" /><figcaption>Voting on topics for the Novoda un-conference — photo courtesy of Leonie Brewin</figcaption></figure><blockquote>Burnout : physical or mental collapse caused by overwork or stress.</blockquote><p>Before attending the unconference, I had been taking on more and more “extra-curricular” activities at work, and with deadlines approaching on my project, I was really struggling with stress. The resulting discussions that took place regarding mental health were fascinating, and really humbling to hear how many other people struggle with this in their day to day lives. It was also incredibly relieving to know that I wasn’t the only one having stress related issues, which aided me in finding a resolution.</p><p>Mental health is still a somewhat taboo subject and conversations like the ones we had at the unconference should happen more often. With this blogpost I hope to kick-start a discussion on workplace stress with the hope that it becomes a topic we can begin to approach with ease, both within and outside of Novoda.</p><p>Following the unconference, I made a particular effort to try and understand the steps I take to battle burnout, and I found there are three points to consider when approaching your own mental health. Get these right and you’re in a much stronger position to be able to jump any hurdles that come your way.</p><h4>Communicate</h4><p>If you can feel yourself getting burnt out or stressed my first piece of advice would be to talk to your employer. Initiating that first point of contact is a crucial first step and in my case, I was completely supported and only received offers of help.</p><p>This is only possible in certain companies however, so it depends on your circumstance. Having a healthy support network of friends and family that you trust to be able to talk to about any struggles you are having can be really beneficial and can help if talking at work is problematic. I often found just chatting about my day to day stresses very therapeutic, and ensured I didn’t overthink, or lose sleep, over potentially menial problems. Trying to get involved in more extra curricular activities outside of work can also help, as this gives fresh perspectives, and a broader friendship circle.</p><h4>Switch off</h4><p>Switching off and allowing yourself proper resting time is vital to maintaining a healthy work-life balance. I find one of the key techniques for allowing yourself to disconnect from work is to set a strict time from which you don’t touch your laptop. This is especially important if you work remotely, as it is far too easy to continue working in the night.</p><p>One technique I employ is to have separate work profiles on my machine which prevents any unwanted notifications after work time. Enabling ‘alarms only’ mode on my phone after work and before I start (6pm - 8am for me) every day has also been particularly helpful.</p><p>Furthermore, taking up a creative hobby such as painting has been incredibly beneficial to my personal mental health. I would advocate this to anyone struggling with burn-out.</p><p>In the past, I have also known a few people to take an extended break from the day-to-day grind of work. It doesn’t even need to be a holiday abroad, just a change of focus can really help “cleanse” your mind. The opportunity to do this is of course incredibly fortunate, and many don’t have this chance.</p><h4>Prioritise your sleep</h4><p>According to the Mental Health Foundation, a good amount of sleep is [vital to maintaining a healthy mind](link!). This is difficult if you have a large commute or other commitments so it is a case of balancing this carefully.</p><p>One key purchase can be a seasonal affective disorder lamp. This is a light you can set to gradually turn off in the evenings and turn on in the mornings. My personal experience is that this results in you waking up much more naturally and also aids in falling asleep if this is something you struggle with.</p><p>As part of this blogpost, I put out a call to other developers in the community for their experiences and advice on mental health and burn out. The response was fantastic. <a href="https://twitter.com/niamh__power/status/968454311435997184">Thanks to all those who responded.</a></p><p>One of the key points of advice I found was to have a healthy life outside of work. Ensuring you exercise and eat well gives you a great foundation to work on your mental health. Taking value in your weekends is also imperative - getting away from home every now and then can do wonders for feeling cabin feverish and can help stop the temptation to work outside of working hours.</p><p>Within your working environment, reminding yourself that at the end of the day, your job is indeed just a job can help you put everything into perspective. Your mental wellbeing is your priority. If the culture is toxic or you’re feeling undue pressure don’t be afraid to start looking at other options if you are able to.</p><p>Additionally, a common snagging point is when developers start moving to more of a senior role. Finding the balance between being more of a mentor / manager and writing code is really difficult, so it is really important to have clear communication with your manager as to what the expectations are. Don’t feel afraid to discuss possible improvements with more senior figures if you’re struggling with the work load or are unsure of the next step to take.</p><p>It takes time, but being able to separate issues at work so you aren’t staying up all night thinking about them is a really vital skill. There are always going to be difficulties, but it is more how you approach them and deal with them mentally that is important.</p><p>Getting a grasp on good time management can be really helpful too. By time boxing your work, you can give yourself more discipline and give realistic expectations to your colleagues. This of course needn’t apply to work only. Other issues that could be troubling you, like personal finances, can be addressed by setting aside some dedicated time for them. You will often find out that a brief but focused session can resolve concerns that have been looming over you for months.</p><p>In addition to this, creating a list each morning of everything you would like to achieve by the end of the day, and then being able to pick this up the next day can help you to visualise the scale of your work, which is often smaller than you might think. This also benefits your evenings, as less of your mental capacity is spent worrying about what you need to do tomorrow.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Py-UT0iClj87ZyrP_JLWUA.jpeg" /></figure><p>For employers, having a friendly and open HR department works wonders. Advocating for a culture of openness and support can ensure employees feel comfortable opening up when they’re struggling. At Novoda, we are planning on meeting fortnightly to discuss techniques on the best ways for the company to tackle any problems people may be facing.</p><p>In all of our offices, we have break-out areas with more relaxed seating, games consoles and an arcade machine. This helps to foster an environment that encourages people to take breaks from their work and relax.</p><p>By making it clear that mental health is as important as physical health, and that taking days off when everything’s a bit overwhelming really helps. When employees are encouraged to work late and there is little tolerance for taking time off, burn-out is the result, as well as deeply unhappy workers. This also can lead to a toxic culture that is far more competitive than healthy.</p><p>Take these steps, and you’ll be well on your way to creating a company culture that is inclusive and open and attracts a fantastic group of people.</p><p>Personally, I only recognised I was struggling after I heard of other’s experiences at the un-conference. This gave me the confidence to talk to those at work who could help, and it’s been great to have that line of communication open for whenever I need it.</p><p>My main point of advice if you are struggling with any mental health issue, would be to talk to someone close to you. Talking to someone you trust makes it real and allows you to start making a plan to tackle it head-on. I hope this blog has given you some confidence to take this step or to make the moves to avoid any problems in the future.</p><p>Finally, the points I’ve raised in this blog talk to those seeking ways to help general day to day stresses, which can ease the root causes of mental illnesses. This doesn’t apply to all, and sometimes counselling and / or medication can be the best way to help. If you aren’t sure, be sure to go and speak to your doctor, or a healthcare professional and they will be able to point you in the right direction. <a href="https://www.nhs.uk/conditions/stress-anxiety-depression/mental-health-helplines/">This page</a> from the NHS in the UK provides some really helpful phone lines, that can offer more professional advice. For those outside of the UK, there are many charities that provide help and advice, and also some fantastic online resources, such as <a href="https://www.betterhelp.com/">BetterHelp</a> for more relevant advice.</p><p>It is particularly important to note that more than one approach could apply to each person, especially if they are experiencing various different symptoms. For example you might benefit from medical treatment but could also need to improve your lifestyle, exercise more, sleep more, or just build better habits. Don’t treat this as a chore (“I already did one thing, therefore I can ignore the remaining difficulties I’m facing”). Use every possible means of improving your life quality and you’ll be on your way to thrive!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e24d4ed5135" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Google effectively as a developer]]></title>
            <link>https://medium.com/@niamhpower/how-to-google-effectively-as-a-developer-4ebe363afe?source=rss-61de4ad69c14------2</link>
            <guid isPermaLink="false">https://medium.com/p/4ebe363afe</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[developer]]></category>
            <category><![CDATA[junior-developer]]></category>
            <category><![CDATA[debugging]]></category>
            <category><![CDATA[software]]></category>
            <dc:creator><![CDATA[Niamh Power]]></dc:creator>
            <pubDate>Thu, 15 Feb 2018 19:06:04 GMT</pubDate>
            <atom:updated>2018-02-15T19:10:00.372Z</atom:updated>
            <content:encoded><![CDATA[<p>One of the key skills as a developer that no-one talks about during any study, is the ability to effectively search for a solution to a problem or error. This is actually a skill that is refined over time, but in this blog post I am going to give you some tips on how to save yourself time and effort.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/250/1*W5W-2l5W2YgQGlxUA7U9DQ.gif" /></figure><h4>Step 1 — Keywords</h4><p>First off, if you’re debugging an error message, pull out any individual information, such as file paths. This allows you to search a wider range of results.</p><h4>Step 2 — Source</h4><p>Where is your error coming from? Is it a library? If so, look up the library’s GitHub page (if it has one), and check out the issues page. It’s likely someone has come to this error already and has had a response with a solution.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*_wxC-lHzK164DszEVUG7pg.gif" /></figure><p>If it hasn’t already been raised and the solution isn’t clear, raise an issue yourself, giving the developers as much information as possible. Also try and get a second opinion on your error, check on another codebase or computer, just in case it’s an issue with your set up.</p><h4>Step 3 — StackOverflow</h4><p>Ah, the trusty StackOverflow, what would we do without it? I often find searching directly into StackOverflow brings up results otherwise hidden by Google.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/480/1*f9Xn7bSy-TWGM-uci38thQ.gif" /></figure><h4><strong>Step 4 — Describe the issue</strong></h4><p>If the problem is due to certain circumstances, try and pick out the keywords from this setup in your search term, as in step 1.</p><h4><strong>Step 5 — Ask your colleagues!</strong></h4><p>If no online methods bear any fruit, ask the person sat next to you! If you’re remote, ask on your company’s slack channel, or whatever communication method you use. Furthermore, there are many Slack groups set up that specialise in certain languages, with often fantastic communities who are incredibly helpful.</p><p>Also, never feel afraid to ask for help. More often than not other developers are more than willing to help you out, and will have faced the same issues you are at some point.</p><h4><strong>Step 6 — Explain it to yourself</strong></h4><p>A popular method for developers is known as ‘rubber duck debugging’. This is where you explain the problem to a rubber duck on your desk. 9 times out of 10 you realise the solution to your problem halfway through explaining it!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/390/1*aLbFKUDos6HHnotO1jXpuQ.gif" /></figure><p>Finally, if you have any tips of your own to share, do comment below!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4ebe363afe" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ReBlog: Does gender matter? My experiences as a female coder]]></title>
            <link>https://medium.com/@niamhpower/reblog-does-gender-matter-my-experiences-as-a-female-coder-fea851ddf81a?source=rss-61de4ad69c14------2</link>
            <guid isPermaLink="false">https://medium.com/p/fea851ddf81a</guid>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[women-in-tech]]></category>
            <dc:creator><![CDATA[Niamh Power]]></dc:creator>
            <pubDate>Wed, 08 Mar 2017 22:59:31 GMT</pubDate>
            <atom:updated>2017-03-08T22:59:31.628Z</atom:updated>
            <content:encoded><![CDATA[<p><em>This is a re-post of my blog for Code Computerlove last year for International Women’s Day. [</em><a href="https://www.codecomputerlove.com/blog/does-gender-matter-my-experiences-as-a-female-coder">https://www.codecomputerlove.com/blog/does-gender-matter-my-experiences-as-a-female-coder</a>]</p><p>International Women’s day: a day to celebrate the achievements of women around the world, but also to highlight the inequalities many still face. Unfortunately, the tech industry is still years behind in terms of representing the real proportion of women in the population. Women still make up a tiny amount of those working in STEM fields, and the digital sector is no different.</p><p>I graduated with a degree in Computer Science last year, and although I would say that the overall experience was fantastic, the approach to girls in the subject at times was not. I can remember a tutorial/workshop session with around 10 of us in a room with a female tutor, and the attitudes of the male students towards her was at times uncomfortable. Another time, a friend was singled out to be put in an extra support group for a particular module, for what appeared to be no reason other than because she was female. The expectation that we would not achieve as much as our male counterparts was rife, and it results in many women who study Computer Science not going into programming based jobs. That’s not to say however that it was all like this, many lecturers were incredibly encouraging, and there were schemes to try and get more women into the field going on at the University.</p><p>Shockingly, the proportion of women in computing is reducing. <a href="http://www.engadget.com/2014/10/20/what-happened-to-all-of-the-women-coders-in-1984/">In the 70s, the number of women in the field was increasing, to a high of 37% enrolled in Computer Science courses in the US in 1984</a>. After this point, that percentage has continued to decline, to less than 20% today. The reasoning behind this is largely because of advertising — all the personal computer advertisements from this point featured solely male figures, implying that this was not something for women to pursue as a career option, or even as a hobby. These issues are still around today, with gaming and an interest in technical fields seen as something more suited to men. Industry is fully aware of the power of advertising to influence behaviour and bring about change. It is in their interest, and everyone else’s, for them to turn these resources to this problem. And yet, not enough is being done.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/735/0*CPOLlYQeTFjoJDtN.jpg" /></figure><p><em>Image source: </em><a href="http://blog.modernmechanix.com/two-bytes-are-better-than-one/"><em>http://blog.modernmechanix.com/two-bytes-are-better-than-one/</em></a></p><p>However, some improvements have been made. A few months ago I went to help at my Mum’s primary school to teach some basic coding skills, as it is now part of the national curriculum, and I was amazed at how quickly both the boys and girls picked it up. Local meet-ups in Manchester such as <a href="http://www.meetup.com/Ladies-of-Code-Manchester/">Ladies of Code</a> provide a platform for female developers to get into the industry and have a friendly environment to learn in. Computer Science is also becoming much more common as a high school subject, though the supply of teachers is very poor. In short, there seems to be an acknowledgement of the issue but the response has been disjointed and at times tokenistic.</p><p>I believe the main root of the issue happens much earlier in life; as children, many girls believe they cannot do the same activities or subjects as their male classmates. Of course, these gender stereotypes do not only affect girls: whilst I was outnumbered in my Physics A-Level class, my Art group had only one male member. In this sense, it is reasonable to conclude that sexism on a recruitment panel is less arbitrary, and more a result of an assimilation of latent gender stereotypes that we as a society possess: girls can’t play with cars, and boys can’t be princesses.</p><p>Although I was only doing my A-levels 5 years ago, I didn’t consider or know much about Computer Science and programming at the time. With the rise of companies such as Google and Facebook, the tech industry is looking ‘cooler’ than ever, and more and more young people are seeing it as an option. Yet the number of women in my field is still woefully low. Personally, I have found this has neither been a detriment, nor an unfair advantage. When applying for my job at Code, there was never an indication that I was in any way different, and this has continued over the last few months of working here. I don’t feel in any way inferior, and that has given me a fantastic environment to learn and develop. For women such as myself, there is a great career to be had in the Computer Science industry and I am loving every minute of it. But I have always been determined to follow this path regardless of the stereotypical comments and attitudes that are inevitable in a male dominated environment. The challenge is to reach women who are interested in Computer Science but are more dissuaded by these issues.</p><p>The problem cannot be solved by simply dedicating a desk in the corner of an office to females. Although this is a positive step in raising the awareness of women in the industry, it is perhaps demeaning to the achievements of the individual and opens women up to assumptions that the decision to give them the job was simply in order to satisfy their female quota. We need to start from the assumption that half of the best talent in the population lies in the female population and we need to realise that the computer industry is shooting itself in the foot by not addressing this problem energetically. The absence of a coordinated, comprehensive and effective national strategy to address this issue is a complete mystery to me.</p><p>Kudos to <a href="https://blog.twitter.com/2015/we-re-committing-to-a-more-diverse-twitter">Twitter</a> and several other high profile companies for directly addressing this issue in the past year. However, I believe that it’ll take more than this to adequately tackle the issue. Grants, changes to the national curriculum and general raised awareness is encouraging. But there’s a long journey ahead. Hopefully, one day companies won’t need to declare the number of their female employees. Maybe if my children follow my career path, when they’re interviewed for jobs, they will be comfortable in the knowledge that they’re entering a blissfully level playing-field, completely devoid of gender stereotypes. I’m not holding my breath though.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fea851ddf81a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why we need to stop ‘career pressure’]]></title>
            <link>https://medium.com/@niamhpower/why-we-need-to-stop-career-pressure-ae3e9c00d2aa?source=rss-61de4ad69c14------2</link>
            <guid isPermaLink="false">https://medium.com/p/ae3e9c00d2aa</guid>
            <category><![CDATA[careers]]></category>
            <category><![CDATA[women-in-tech]]></category>
            <category><![CDATA[animation]]></category>
            <category><![CDATA[creative]]></category>
            <category><![CDATA[career-advice]]></category>
            <dc:creator><![CDATA[Niamh Power]]></dc:creator>
            <pubDate>Sun, 04 Dec 2016 23:07:20 GMT</pubDate>
            <atom:updated>2016-12-04T23:07:20.751Z</atom:updated>
            <content:encoded><![CDATA[<p>I was inspired to write this post after speaking to colleagues at work about what they wanted to do with their lives when they were teenagers. I find it slightly depressing that I wasn’t surprised to find that a fair few have ended up in careers that would not be their first choice in an ideal world, especially when those dreams were to have a job in a creative industry.</p><p>Personally, I have always wanted to do computer animation — ever since watching Shrek as a kid and seeing one of the ‘making of’ documentaries. I’ve always loved drawing and tech and it seemed like the perfect combination. Unfortunately as I got older I was persuaded that this wasn’t the best career choice, either because ‘it’s too difficult to get into’, or ‘there isn’t any money in it’. Even ‘you’re too smart for that’. Computer Animation at Bournemouth required 3 B’s if I remember correctly at the time; I was predicted to get 3 A’s, which apparently made it below me. (This may be me being incredibly cynical, but it definitely felt like this at the time!)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*saO4fcyT0IQvGAWHydFM8g.jpeg" /><figcaption>One of my drawings, age 5</figcaption></figure><p>So, I ended up choosing to study Physics at university at the age of 17. My intention was to do this and then somehow get involved with working on Physics engines for games etc. On results day however, I changed my mind last minute to choose Computer Science, which I felt would allow me to pursue potentially creative outlets more than Physics would.</p><p>I’m now working as an app developer in both iOS and Android, and I really do love my job; I get to work on the design and functionality of the apps, which is great. But at times I find myself wishing I had had the confidence to pursue what I wanted to do from 13. The stigma that creative subjects aren’t for those who happen to be good at exams needs to be tackled. I do accept that yes, there aren’t as many jobs in those sectors, and the pay may not be as good. Plus, I am now approaching a position where I could pursue animation as a hobby and potentially freelance in the future, but not all would have that opportunity, and none of us are getting any younger!</p><p>The idea that in order to have a successful life you have to have a well paid job at a successful company is incredibly damaging to creatives, and demeans the aspirations of what I imagine to be thousands of young adults.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ae3e9c00d2aa" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>