-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfeed.xml
More file actions
1863 lines (1255 loc) · 244 KB
/
feed.xml
File metadata and controls
1863 lines (1255 loc) · 244 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>iOS/Android [ChaosOverFlow]</title>
<description>iOS Android ChaosOverFlow Chat room site. Source for iOS and Android beginner tutorials.
</description>
<link>http://shubhank101.github.io/iOSAndroidChaosOverFlow/</link>
<atom:link href="http://shubhank101.github.io/iOSAndroidChaosOverFlow/feed.xml" rel="self" type="application/rss+xml"/>
<pubDate>Fri, 02 Sep 2016 23:40:33 +0530</pubDate>
<lastBuildDate>Fri, 02 Sep 2016 23:40:33 +0530</lastBuildDate>
<generator>Jekyll v3.1.3</generator>
<item>
<title>Push notification in ios Using fcm (swift)</title>
<description><h2 id="what-is-fcm">What is FCM?</h2>
<p><strong>FCM (Firebase Cloud Messaging)</strong> replaces Google Cloud Messaging (GCM) as the API to send/receive push notifications from.<br />
Most of the popular apps in the market uses push notifications to engage the user and i am sure you are interested to implement them in your app too so follow along.</p>
<h3 id="how-does-fcm-work">How does FCM work</h3>
<p><img src="https://firebase.google.com/docs/cloud-messaging/images/messaging-overview.png" alt="FCM Diagram" /></p>
<p>As shown in the figure, the FCM is the middle ware between your device and the server.<br />
You send the message you want to send to the devices to the Firebase server and it redirects it to the appropriate device. It handles all the middle ware part like scheduling notification time, failure and success rate, unique device tokens etc.</p>
<p>We can use a http/xmpp server to send the message to the FCM server but in our tutorial we use the handy tool provided by the FCM guys - <strong>Notification console</strong>.</p>
<hr />
<h2 id="theory-of-how-push-notification-work-on-ios">Theory of how Push notification work on iOS</h2>
<p>Before progressing to code and FCM working for push notification, we should do a little review of how push notification works.</p>
<p><strong>Apple Push Notification Service (APNS)</strong> is responsible for managing devices and sending message to them. We can send our push notification payload to the APNS server with the device token and it takes care of scheduling the message as well as success/failure rate.<br />
Each device is <strong>uniquely identified by its device token</strong>. Further, an app require user to grant the permission to send push notification to user device. If the user declines - you won’t get a device token and therefore can’t target the user.</p>
<hr />
<h2 id="step-1-asking-permission-for-push-notifications">Step 1. Asking Permission for push notifications</h2>
<p>Create a new Xcode Project and name it <strong>FCM_Tutorial</strong>.</p>
<p>Now note down the <strong>bundle id</strong> and store it in a separate place, we will need it to make the <code class="highlighter-rouge">GoogleService-Info</code> plist file later when we add Firebase to our app.</p>
<p>To get the device token - we need to ask user permission for sending alert, banner and/or sound push.</p>
<p><img src="http://i.imgur.com/j02xEHm.png?1" alt="Push Notif" /></p>
<p>If user allow, the device will contact the APNS server and a push notification will be passed on to the App delegate function <strong>didRegisterForDeviceToken</strong>.
Any error if occured is received in the function <strong>didFailtoregister</strong></p>
<p>Update your AppDelegate’s <code class="highlighter-rouge">didFinishLaunchingWithOptions</code> method with the following code</p>
<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="kd">func</span> <span class="nf">application</span><span class="p">(</span><span class="nv">application</span><span class="p">:</span> <span class="kt">UIApplication</span><span class="p">,</span> <span class="n">didFinishLaunchingWithOptions</span> <span class="nv">launchOptions</span><span class="p">:</span> <span class="p">[</span><span class="kt">NSObject</span><span class="p">:</span> <span class="kt">AnyObject</span><span class="p">]?)</span> <span class="o">-&gt;</span> <span class="kt">Bool</span> <span class="p">{</span>
<span class="c1">// Override point for customization after application launch.</span>
<span class="k">let</span> <span class="nv">notificationTypes</span><span class="p">:</span> <span class="kt">UIUserNotificationType</span> <span class="o">=</span> <span class="p">[</span><span class="kt">UIUserNotificationType</span><span class="o">.</span><span class="kt">Alert</span><span class="p">,</span> <span class="kt">UIUserNotificationType</span><span class="o">.</span><span class="kt">Badge</span><span class="p">,</span> <span class="kt">UIUserNotificationType</span><span class="o">.</span><span class="kt">Sound</span><span class="p">]</span>
<span class="k">let</span> <span class="nv">notificationSettings</span> <span class="o">=</span> <span class="kt">UIUserNotificationSettings</span><span class="p">(</span><span class="nv">forTypes</span><span class="p">:</span> <span class="n">notificationTypes</span><span class="p">,</span> <span class="nv">categories</span><span class="p">:</span> <span class="kc">nil</span><span class="p">)</span>
<span class="n">application</span><span class="o">.</span><span class="nf">registerUserNotificationSettings</span><span class="p">(</span><span class="n">notificationSettings</span><span class="p">)</span>
<span class="n">application</span><span class="o">.</span><span class="nf">registerForRemoteNotifications</span><span class="p">()</span>
<span class="k">return</span> <span class="kc">true</span>
<span class="p">}</span>
</code></pre></figure>
<p>We create an array defining the types of notification we need and then call <code class="highlighter-rouge">registerUserNotificationSettings</code> so that the OS ask for the permission from the user.</p>
<p><strong>You cannot test push notification on simulator so make sure to have a apple dev account and a device</strong></p>
<h3 id="step-2-adding-firebase-to-your-project">Step 2. Adding Firebase to your project</h3>
<blockquote>
<p>Prerequisite : You need to have Xcode 7.3 or higher for the FCM to work.</p>
</blockquote>
<p>Head over to <a href="https://console.firebase.google.com/">Firebase console</a> and click <strong>Create New Project</strong>. Enter FCM_Tutorial as the name project and click create project. You will be redirected to a screen like this</p>
<p><img src="http://i.imgur.com/41Rq8Ij.jpg" alt="Firebase Console" /></p>
<p>Click Add firebase to your iOS project and in the popup - <strong>Enter your project bundle id</strong></p>
<p><img src="http://i.imgur.com/gwUb9E1.jpg" alt="Bundle id popup" /></p>
<p>Press Add app and now you will get the <strong>GoogleService-Info.plist</strong> downloaded automatically. Now keep pressing continue to finish the integration steps and get back to the project.</p>
<p>Drag the plist you downloaded into your project root (where .xcodeProj file is). The plist file actually includes all the relevant settings for the firebase app including the firebase database url for your app.</p>
<h3 id="setup-pods">Setup Pods</h3>
<p>Open a terminal and execute <strong>pod init</strong> in your project directory. Open the pod file in text editor or in Xcode and add these pods to the app target</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml">pod 'Firebase/Core'
pod 'Firebase/Messaging'</code></pre></figure>
<p>Run <strong>pod install</strong> in terminal and once completed open the <strong>.xcworkspace</strong> file to open the project.</p>
<h4 id="intializing-firebase-in-our-app">Intializing Firebase in our app</h4>
<p>Open up Appdelegate.swift <code class="highlighter-rouge">didFinishLaunching</code> method and in it add the line
<code class="highlighter-rouge">
FIRApp.configure()
</code>
Make sure to <strong>import Firebase</strong> in each class you use Firebase.</p>
<h3 id="step-3-implementing-token-registeration-methods">Step 3. Implementing token registeration methods</h3>
<figure class="highlight"><pre><code class="language-swift" data-lang="swift"> <span class="kd">func</span> <span class="nf">application</span><span class="p">(</span><span class="nv">application</span><span class="p">:</span> <span class="kt">UIApplication</span><span class="p">,</span>
<span class="n">didRegisterForRemoteNotificationsWithDeviceToken</span> <span class="nv">deviceToken</span><span class="p">:</span> <span class="kt">NSData</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">FIRInstanceID</span><span class="o">.</span><span class="nf">instanceID</span><span class="p">()</span><span class="o">.</span><span class="nf">setAPNSToken</span><span class="p">(</span><span class="n">deviceToken</span><span class="p">,</span> <span class="nv">type</span><span class="p">:</span> <span class="kt">FIRInstanceIDAPNSTokenType</span><span class="o">.</span><span class="kt">Sandbox</span><span class="p">)</span>
<span class="kt">FIRInstanceID</span><span class="o">.</span><span class="nf">instanceID</span><span class="p">()</span><span class="o">.</span><span class="nf">setAPNSToken</span><span class="p">(</span><span class="n">deviceToken</span><span class="p">,</span> <span class="nv">type</span><span class="p">:</span> <span class="kt">FIRInstanceIDAPNSTokenType</span><span class="o">.</span><span class="kt">Prod</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="kt">FIRInstanceID</span><span class="o">.</span><span class="nf">instanceID</span><span class="p">()</span><span class="o">.</span><span class="nf">token</span><span class="p">())</span>
<span class="k">let</span> <span class="nv">tokenChars</span> <span class="o">=</span> <span class="kt">UnsafePointer</span><span class="o">&lt;</span><span class="kt">CChar</span><span class="o">&gt;</span><span class="p">(</span><span class="n">deviceToken</span><span class="o">.</span><span class="n">bytes</span><span class="p">)</span>
<span class="k">var</span> <span class="nv">tokenString</span> <span class="o">=</span> <span class="s">""</span>
<span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="mi">0</span><span class="o">..&lt;</span><span class="n">deviceToken</span><span class="o">.</span><span class="n">length</span> <span class="p">{</span>
<span class="n">tokenString</span> <span class="o">+=</span> <span class="kt">String</span><span class="p">(</span><span class="nv">format</span><span class="p">:</span> <span class="s">"%02.2hhx"</span><span class="p">,</span> <span class="nv">arguments</span><span class="p">:</span> <span class="p">[</span><span class="n">tokenChars</span><span class="p">[</span><span class="n">i</span><span class="p">]])</span>
<span class="p">}</span>
<span class="nf">print</span><span class="p">(</span><span class="s">"tokenString: </span><span class="se">\(</span><span class="n">tokenString</span><span class="se">)</span><span class="s">"</span><span class="p">)</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="nf">application</span><span class="p">(</span><span class="nv">application</span><span class="p">:</span> <span class="kt">UIApplication</span><span class="p">,</span> <span class="n">didFailToRegisterForRemoteNotificationsWithError</span> <span class="nv">error</span><span class="p">:</span> <span class="kt">NSError</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="n">error</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></figure>
<p><strong>didRegisterForRemoteNotificationsWithDeviceToken</strong></p>
<p>In this method we save the device token to our FIRInstanceID so that our unique device token is made for Firebase.</p>
<p><strong>didFailToRegisterForRemoteNotificationsWithError</strong><br />
<strong>keep a lookout</strong> for this method, every time the app fails to register for remote notification - it will show the error details here.</p>
<p>If you run the app in simulator now: You will face the Notification alert shown in step 1. Clicking Allow will give a error in the logs like</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml">2016-09-01 19:19:04.639: <span class="nt">&lt;FIRInstanceID</span><span class="err">/WARNING</span><span class="nt">&gt;</span> Failed to fetch APNS token Error Domain=NSCocoaErrorDomain Code=3010 "REMOTE_NOTIFICATION_SIMULATOR_NOT_SUPPORTED_NSERROR_DESCRIPTION"
UserInfo={NSLocalizedDescription=REMOTE_NOTIFICATION_SIMULATOR_NOT_SUPPORTED_NSERROR_DESCRIPTION}</code></pre></figure>
<p>Make sure to test on Device!.</p>
<hr />
<h2 id="step-4-creating-app-certificate-and-provisioning">Step 4. Creating App certificate and provisioning</h2>
<h3 id="what-they-are-and-why-are-they-needed">What they are and why are they needed</h3>
<p>You must already be knowing that to run app on devices - we need to have provisioning profile with the device udid added in it.
To send push notifications we also need to create separate push certificate and upload the <strong>.pem</strong> or <strong>.p12</strong> file on our server. Firebase require you to upload the .p12 file.</p>
<h3 id="simple-way---let-xcode-create-them">Simple way - Let Xcode create them</h3>
<p>Xcode 7 has the option to automatically create provisioning profile and certificates for you.</p>
<p>Go to preferences in Xcode and Add your apple developer account if not already added.
<img src="http://i.imgur.com/pMjxOuA.png" alt="Xcode Account" /></p>
<p>Next up is to set the team in Xcode. This will make Xcode use the appt. apple account to create the app id and provisioning for our app.<br />
Here is a screenshot which shows where to set the team</p>
<p><img src="http://i.imgur.com/TeUQS9d.jpg" alt="Set Team" /></p>
<p>Then head over to <strong>Capabilities</strong> tab in your target and Enable Push Notifications
<img src="http://i.imgur.com/KPRpA2d.jpg" alt="Capabilities" />
<img src="http://i.imgur.com/NMIod1v.jpg" alt="Enabling Push" />
Xcode will now register your app id and enable the push certificates for you.</p>
<h3 id="longer-route---creating-certificate-and-provisioning-manually-for-push">Longer route - Creating certificate and provisioning manually for push</h3>
<p><strong>If the easy way does not work and you don’t see the token still after running the app</strong>, you would have to take the longer route of creating provisioning and certificates using Keychain Access and Apple Developer Portal.</p>
<p><em>I for personally blame Apple and Xcode for the provisioning messup :)</em></p>
<p>Open up <strong>Keychain Access</strong> app by finding it in the LaunchPad.</p>
<p>Select Request a Certificate from a Certificate Authority in the App Menu
<img src="http://i.imgur.com/IYkusVJ.jpg" alt="Create a Certificate" /></p>
<p>In the New Window that opens, add the email and name and then select the option to save it to disk.</p>
<p><strong>Note: Make sure to enter a name which has clear purpose, It is helpful in finding out keychain key in further steps</strong></p>
<p><img src="http://i.imgur.com/5YlDnda.jpg" alt="Create Certificate Dialog" /></p>
<p>Save the certificate to a place where you can locate it later on.</p>
<p>Now proceed to <a href="http://developer.apple.com">Developer Center</a> and login into your account.<br />
In the App Id section - click on your app till you reach a similar screen with Edit button</p>
<p><img src="http://i.imgur.com/2JH0fVt.jpg" alt="Edit App id" />
Click Edit and Scroll down to the Push certificate section
<strong>Create a Development SSL certificate as shown in the image</strong></p>
<p><img src="http://i.imgur.com/19pFIxj.jpg" alt="Create Push Certificate for App Id" /></p>
<p>Click Continue in the below screen
<img src="http://i.imgur.com/8oypmGx.jpg" alt="Create Certificate" /></p>
<p>Select the certificate where you saved it
<img src="http://i.imgur.com/WhGsPG4.jpg" alt="Create Certificate" /></p>
<p>Download the aps certificate created and double click it so that it is added to the Keychain.</p>
<p><img src="http://i.imgur.com/KfoAnX2.jpg" alt="Certificate in keychain" /></p>
<p><strong>Right Click the Apple Push Services Key Row and Click Export</strong>
Save the .p12 file now in a safe place and skip setting a password for the exported file for now.</p>
<h4 id="last-step-is-now-to-download-the-provisioning-profile">Last Step is now to download the provisioning profile.</h4>
<p>Everytime you update the certificates for push for your app id, the provisioning profiles are required to be regenerated so that they have the entitlements set.</p>
<p>Go to the provisioning center and create a new/edit development provisioning profile <strong>(make sure it has your development device udid)</strong> for your app and download it.<br />
Open it up in your xcode and set it as the Development provisioning profile in <strong>Build Settings</strong></p>
<h3 id="step-5-testing-push-using-firebase-console">Step 5. Testing push using Firebase Console</h3>
<p>Time to test the push feature finally after all this setup :)</p>
<p>You can now use Notification Console to start sending push notification to your app. Go to the notification console as shown in the following pics</p>
<blockquote>
<p><strong>Note: For the notification to show make sure to kill the app after you get the token</strong></p>
</blockquote>
<p><img src="http://i.imgur.com/4Av4hyj.jpg" alt="Notification Console" />
<img src="http://i.imgur.com/kc0UhSP.jpg" alt="Compose Message" /></p>
<p>The token to use is the one printed using this line</p>
<figure class="highlight"><pre><code class="language-swift" data-lang="swift"> <span class="nf">print</span><span class="p">(</span><span class="kt">FIRInstanceID</span><span class="o">.</span><span class="nf">instanceID</span><span class="p">()</span><span class="o">.</span><span class="nf">token</span><span class="p">())</span></code></pre></figure>
<p>On the lock screen - you should see the app icon with the title <code class="highlighter-rouge">FIRST FCM MESSAGE</code></p>
<h2 id="other-things-to-keep-in-mind">Other Things to Keep in Mind</h2>
<p><strong>Few important things to keep in mind before finishing up</strong></p>
<p>1) iOS App while in background/foreground receives the notification in Appdelegate <strong>didReceiveRemoteNotification</strong> method. It is your resposibility to show the alert as well as any other action in this case by parsing the payload</p>
<figure class="highlight"><pre><code class="language-swift" data-lang="swift"> <span class="kd">func</span> <span class="nf">application</span><span class="p">(</span><span class="nv">application</span><span class="p">:</span> <span class="kt">UIApplication</span><span class="p">,</span> <span class="n">didReceiveRemoteNotification</span> <span class="nv">userInfo</span><span class="p">:</span> <span class="p">[</span><span class="kt">NSObject</span> <span class="p">:</span> <span class="kt">AnyObject</span><span class="p">],</span> <span class="n">fetchCompletionHandler</span> <span class="nv">completionHandler</span><span class="p">:</span> <span class="p">(</span><span class="kt">UIBackgroundFetchResult</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Void</span><span class="p">)</span> <span class="p">{</span>
<span class="nf">print</span><span class="p">(</span><span class="n">userInfo</span><span class="p">)</span>
<span class="p">}</span></code></pre></figure>
<p>2) <strong>App Store/Adhoc build will use the Distribution SSL Certificate for the Push certificate.</strong></p>
<p>Make sure to repeat the steps above to make the distribution push certificate when submitting app to the store.</p>
<h2 id="conclusion">Conclusion</h2>
<p><strong>Thank you</strong> for reading this far. For any questions you are welcome to ask in our chat room.</p>
<h2 id="next-steps">Next Steps</h2>
<p>Please take a look at our other <a href="../../tutorials">tutorials</a> :)</p>
</description>
<pubDate>Sat, 02 Jul 2016 00:00:00 +0530</pubDate>
<link>http://shubhank101.github.io/iOSAndroidChaosOverFlow/2016/07/Push-Notification-in-iOS-using-FCM-(Swift)</link>
<guid isPermaLink="true">http://shubhank101.github.io/iOSAndroidChaosOverFlow/2016/07/Push-Notification-in-iOS-using-FCM-(Swift)</guid>
<category>intro</category>
<category>beginner</category>
<category>swift</category>
<category>tutorial</category>
<category>lessons</category>
</item>
<item>
<title>Implementing Fcm ( Firebase Cloud Messaging ) In Android App</title>
<description><blockquote>
<p>The final project is available for download from the <a href="https://github.com/Shubhank101/iOSAndroidChaosOverFlow-Projects">Github repository</a></p>
</blockquote>
<h2 id="what-is-fcm">What is FCM?</h2>
<p><strong>FCM (Firebase Cloud Messaging)</strong> replaces Google Cloud Messaging (GCM) as the API to send/receive push notifications from.<br />
Most of the popular apps in the market uses push notifications to engage the user and i am sure you are interested to implement them in your app too so follow along.</p>
<h3 id="how-does-fcm-work">How does FCM work</h3>
<p><img src="https://firebase.google.com/docs/cloud-messaging/images/messaging-overview.png" alt="FCM Diagram" /></p>
<p>As shown in the figure, the FCM is the middle ware between your device and the server.<br />
You send the message you want to send to the devices to the Firebase server and it redirects it to the appropriate device. It handles all the middle ware part like scheduling notification time, failure and success rate, unique device tokens etc.</p>
<p>We can use a http/xmpp server to send the message to the FCM server but in our tutorial we use the handy tool provided by the FCM guys - <strong>Notification console</strong>.</p>
<h3 id="step-1-setting-up-the-android-project">Step 1. Setting up the Android project</h3>
<blockquote>
<p>Prerequisite : You need to have Studio with version <strong>1.5</strong> or higher for the services to work.</p>
</blockquote>
<p>Create a new Android Studio Project and name it FCM_Tutorial.
Now note down the <strong>package name</strong>, we will need it to make the <code class="highlighter-rouge">google-services.json</code> file.</p>
<p>Head over to <a href="https://console.firebase.google.com/">Firebase console</a> and click <strong>Create New Project</strong>. Enter FCM_Tutorial as the name project and click create project. You will be redirected to a screen like this</p>
<p><img src="http://i.imgur.com/41Rq8Ij.jpg" alt="Firebase Console" /></p>
<p>Click Add firebase to your Android project and in the popup - <strong>Enter your package name</strong></p>
<p><img src="http://i.imgur.com/s7EuCON.jpg" alt="Package popup" /></p>
<p>Press Add app and now you will get the <strong>google-services.json</strong> downloaded automatically. Now keep pressing continue to finish the integration steps and get back to the project.</p>
<p>Drag the json you downloaded into your project root (where .build gradle file is of the app module). The json file actually includes all the relevant settings for the firebase app including the firebase database url for your app.</p>
<h3 id="setup-gradle">Setup Gradle</h3>
<p>Open your project build.gradle file and add the following dependencies</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml"> dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
classpath 'com.google.gms:google-services:3.0.0'
}</code></pre></figure>
<p>Now open your app module build.grade and add these dependencies</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml"> compile 'com.google.firebase:firebase-core:9.0.1'
compile 'com.google.firebase:firebase-messaging:9.0.1'</code></pre></figure>
<p>At the end of the file we need to apply our google play servcies plugin :</p>
<p><code class="highlighter-rouge">apply plugin: 'com.google.gms.google-services'</code></p>
<p>Sync your gradle and you will have the firebase setup in your project.</p>
<h3 id="step-2-creating-our-tokenservice">Step 2. Creating our TokenService</h3>
<p>Each device need to be uniquely identified so that we can check success/failure and target individual user. Firebase provides <strong>FirebaseInstanceId</strong> class which takes care of creating unique device token for the current device.<br />
The token is refreshed randomly based on duration or other things so to avoid checking each time for new token, We have to use a Service class that extends <strong>FirebaseInstanceIdService</strong>.<br />
In it, the <strong>onTokenRefresh</strong> is called each time a new token is generated.</p>
<p>So it’s time to create a new class in our project. Name it <strong>TokenService.java</strong> and have it extend <strong>FirebaseInstanceIdService</strong>. Here is our implementation</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java">
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">TokenService</span> <span class="kd">extends</span> <span class="n">FirebaseInstanceIdService</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="n">onTokenRefresh</span><span class="o">()</span> <span class="o">{</span>
<span class="c1">// Get updated InstanceID token.</span>
<span class="n">String</span> <span class="n">refreshedToken</span> <span class="o">=</span> <span class="n">FirebaseInstanceId</span><span class="o">.</span><span class="na">getInstance</span><span class="o">().</span><span class="na">getToken</span><span class="o">();</span>
<span class="n">Log</span><span class="o">.</span><span class="na">w</span><span class="o">(</span><span class="s">"notification"</span><span class="o">,</span> <span class="n">refreshedToken</span><span class="o">);</span>
<span class="n">sendRegistrationToServer</span><span class="o">(</span><span class="n">refreshedToken</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="kt">void</span> <span class="n">sendRegistrationToServer</span><span class="o">(</span><span class="n">String</span> <span class="n">token</span><span class="o">)</span> <span class="o">{</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p>We get the token from the FirebaseInstanceId instance and just log it currently to the logcat so that we can use it later. You can send it to server in a production app to store it in your db.</p>
<h3 id="step-3-registering-our-service-in-manifest">Step 3. Registering our service in manifest</h3>
<p>For our TokenService to actually work we need to make sure it is added to our <strong>AndroidManifest.xml</strong> file.
Open up the manifest and inside our <strong>application</strong> tag add the service lines</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml"> <span class="nt">&lt;service</span>
<span class="na">android:name=</span><span class="s">".TokenService"</span><span class="nt">&gt;</span>
<span class="nt">&lt;intent-filter&gt;</span>
<span class="nt">&lt;action</span> <span class="na">android:name=</span><span class="s">"com.google.firebase.INSTANCE_ID_EVENT"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/intent-filter&gt;</span>
<span class="nt">&lt;/service&gt;</span></code></pre></figure>
<p>Run the app and you should see the token in Logcat.</p>
<p><img src="http://i.imgur.com/o2oICrI.jpg" alt="Token in Logcat" /></p>
<h3 id="step-4-testing-a-push-notification-through-the-notification-console">Step 4. Testing A Push notification through the Notification Console</h3>
<p>This was really easy right. You can now use Notification Console to start sending push notification to your app. Go to the notification console as shown in the following pics</p>
<blockquote>
<p><strong>Note: For the notification to show make sure the app is in background and not in foreground</strong></p>
</blockquote>
<p><img src="http://i.imgur.com/4Av4hyj.jpg" alt="Notification Console" />
<img src="http://i.imgur.com/kc0UhSP.jpg" alt="Compose Message" /></p>
<p>In the second screenshot, you can set the Title and also send messages based on filter like all devices/groups/particular device, adjust time for your notification. We will use the <strong>Single device</strong> and use the token we got in #step 3 of our tutorial.</p>
<p>After filling the title and token, scroll down and click Send Message. You will see the notification show up in your device notification panel.</p>
<h3 id="step-5-creating-our-fcmmessagereceiverservice">Step 5. Creating our FCMMessageReceiverService</h3>
<p>Well our app is able to receive notifications and show in our app but in actual we don’t have any code in our app that actually does the part of displaying the notification. This can be tested by doing <strong>step 4</strong> with app in foreground, you won’t see the notification with app in foreground.</p>
<p>This is a feature of Firebase; it shows the notification automatically if the app is in background. However if the app is in foreground, we have to extend <strong>FirebaseMessagingService</strong>.</p>
<p>This class has a method <strong>onMessageReceived</strong> which is called when a FCM is received in foreground. Create a new class in your project and name it <strong>FCMMessageReceiverService</strong>.</p>
<p>Here is our implementation :</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">FCMMessageReceiverService</span> <span class="kd">extends</span> <span class="n">FirebaseMessagingService</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="n">onMessageReceived</span><span class="o">(</span><span class="n">RemoteMessage</span> <span class="n">remoteMessage</span><span class="o">)</span> <span class="o">{</span>
<span class="n">Log</span><span class="o">.</span><span class="na">w</span><span class="o">(</span><span class="s">"fcm"</span><span class="o">,</span> <span class="s">"received notification"</span><span class="o">);</span>
<span class="n">sendNotification</span><span class="o">(</span><span class="n">remoteMessage</span><span class="o">.</span><span class="na">getNotification</span><span class="o">().</span><span class="na">getTitle</span><span class="o">());</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="kt">void</span> <span class="n">sendNotification</span><span class="o">(</span><span class="n">String</span> <span class="n">messageBody</span><span class="o">)</span> <span class="o">{</span>
<span class="n">Intent</span> <span class="n">intent</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Intent</span><span class="o">(</span><span class="k">this</span><span class="o">,</span> <span class="n">MainActivity</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
<span class="n">intent</span><span class="o">.</span><span class="na">addFlags</span><span class="o">(</span><span class="n">Intent</span><span class="o">.</span><span class="na">FLAG_ACTIVITY_CLEAR_TOP</span><span class="o">);</span>
<span class="n">PendingIntent</span> <span class="n">pendingIntent</span> <span class="o">=</span> <span class="n">PendingIntent</span><span class="o">.</span><span class="na">getActivity</span><span class="o">(</span><span class="k">this</span><span class="o">,</span> <span class="mi">0</span> <span class="o">,</span> <span class="n">intent</span><span class="o">,</span>
<span class="n">PendingIntent</span><span class="o">.</span><span class="na">FLAG_ONE_SHOT</span><span class="o">);</span>
<span class="n">Uri</span> <span class="n">defaultSoundUri</span><span class="o">=</span> <span class="n">RingtoneManager</span><span class="o">.</span><span class="na">getDefaultUri</span><span class="o">(</span><span class="n">RingtoneManager</span><span class="o">.</span><span class="na">TYPE_NOTIFICATION</span><span class="o">);</span>
<span class="n">NotificationCompat</span><span class="o">.</span><span class="na">Builder</span> <span class="n">notificationBuilder</span> <span class="o">=</span> <span class="k">new</span> <span class="n">NotificationCompat</span><span class="o">.</span><span class="na">Builder</span><span class="o">(</span><span class="k">this</span><span class="o">)</span>
<span class="o">.</span><span class="na">setSmallIcon</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">mipmap</span><span class="o">.</span><span class="na">ic_launcher</span><span class="o">)</span>
<span class="o">.</span><span class="na">setContentTitle</span><span class="o">(</span><span class="n">messageBody</span><span class="o">)</span>
<span class="o">.</span><span class="na">setAutoCancel</span><span class="o">(</span><span class="kc">false</span><span class="o">)</span>
<span class="o">.</span><span class="na">setSound</span><span class="o">(</span><span class="n">defaultSoundUri</span><span class="o">);</span>
<span class="n">NotificationManager</span> <span class="n">notificationManager</span> <span class="o">=</span>
<span class="o">(</span><span class="n">NotificationManager</span><span class="o">)</span> <span class="n">getSystemService</span><span class="o">(</span><span class="n">Context</span><span class="o">.</span><span class="na">NOTIFICATION_SERVICE</span><span class="o">);</span>
<span class="n">notificationManager</span><span class="o">.</span><span class="na">notify</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="n">notificationBuilder</span><span class="o">.</span><span class="na">build</span><span class="o">());</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p>We override onMessageReceived and call the <code class="highlighter-rouge">sendNotification</code> method with the FCM title. The notification method simply creates a Notification and show it.</p>
<h3 id="step-6-registering-our-message-service-in-manifest">Step 6. Registering our message service in manifest</h3>
<p>Just like TokenService our FCMMessageReceiverService needs to be registered in manifest too so that it is visible and can be called by Firebase. Update your manifest application tag with</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml"> <span class="nt">&lt;service</span>
<span class="na">android:name=</span><span class="s">".FCMMessageReceiverService"</span><span class="nt">&gt;</span>
<span class="nt">&lt;intent-filter&gt;</span>
<span class="nt">&lt;action</span> <span class="na">android:name=</span><span class="s">"com.google.firebase.MESSAGING_EVENT"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/intent-filter&gt;</span>
<span class="nt">&lt;/service&gt;</span></code></pre></figure>
<h4 id="testing-our-push-notification-once-again">Testing our push notification once again</h4>
<p>Go Ahead and do the <strong>Step 4</strong> again with app in foreground. You will see the logcat show the message <em>received notification</em> as well as the notification appear in the notification panel.</p>
<p><img src="http://i.imgur.com/XFt3z28.jpg" alt="Notification Message in Device" /></p>
<h2 id="conclusion">Conclusion</h2>
<p><strong>Thank you</strong> for reading this far. For any questions you are welcome to ask in our chat room.</p>
<h2 id="next-steps">Next Steps</h2>
<p>Please take a look at our other <a href="../../tutorials">tutorials</a> :)</p>
</description>
<pubDate>Thu, 02 Jun 2016 00:00:00 +0530</pubDate>
<link>http://shubhank101.github.io/iOSAndroidChaosOverFlow/2016/06/Implementing-FCM-(-Firebase-Cloud-Messaging-)-in-Android-App</link>
<guid isPermaLink="true">http://shubhank101.github.io/iOSAndroidChaosOverFlow/2016/06/Implementing-FCM-(-Firebase-Cloud-Messaging-)-in-Android-App</guid>
<category>intro</category>
<category>beginner</category>
<category>swift</category>
<category>tutorial</category>
<category>lessons</category>
</item>
<item>
<title>Todo App With Firebase Part 1 (android)</title>
<description><blockquote>
<p>This tutorial assumes you are familiar with basics of Android development including Android Studio, java and gradle.</p>
</blockquote>
<h1 id="what-is-firebase">What is Firebase?</h1>
<p><img src="https://1.bp.blogspot.com/-YIfQT6q8ZM4/Vzyq5z1B8HI/AAAAAAAAAAc/UmWSSMLKtKgtH7CACElUp12zXkrPK5UoACLcB/s1600/image00.png" alt="Firebase logo" /></p>
<p><strong>Firebase</strong> is a multi purpose sdk which can be used to integrate push notifications in your app, app analytics and a whole lot of other features which you can review on its site.</p>
<p>We are going to use <strong>Firebase Realtime Database</strong> here to develop a simple To-do app.</p>
<h2 id="step-1-setting-up-android-project">Step 1. Setting up Android Project</h2>
<blockquote>
<p>Prerequisite : You need to have Studio with version <strong>1.5</strong> or higher for the services to work.</p>
</blockquote>
<p>Create a new Android Studio Project and name it TodoApp.
Now note down the <strong>package name</strong>, we will need it to make the <code class="highlighter-rouge">google-services.json</code> file.</p>
<p>Head over to <a href="https://console.firebase.google.com/">Firebase console</a> and click <strong>Create New Project</strong>. Enter TodoApp as the name project and click create project. You will be redirected to a screen like this</p>
<p><img src="http://i.imgur.com/41Rq8Ij.jpg" alt="Firebase Console" /></p>
<p>Click Add firebase to your Android project and in the popup - <strong>Enter your package name</strong></p>
<p><img src="http://i.imgur.com/s7EuCON.jpg" alt="Package popup" /></p>
<p>Press Add app and now you will get the <strong>google-services.json</strong> downloaded automatically. Now keep pressing continue to finish the integration steps and get back to the project.</p>
<p>Drag the json you downloaded into your project root (where .build gradle file is of the app module). The json file actually includes all the relevant settings for the firebase app including the firebase database url for your app.</p>
<h3 id="setup-gradle">Setup Gradle</h3>
<p>Open your project build.gradle file and add the following dependencies</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml"> dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
classpath 'com.google.gms:google-services:3.0.0'
}</code></pre></figure>
<p>Now open your app module build.grade and add these dependencies</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml"> compile 'com.google.firebase:firebase-core:9.0.1'
compile 'com.google.firebase:firebase-database:9.0.1'</code></pre></figure>
<p>At the end of the file we need to apply our google play servcies plugin :</p>
<p><code class="highlighter-rouge">apply plugin: 'com.google.gms.google-services'</code></p>
<p>Sync your gradle and you will have the firebase setup in your project.</p>
<h2 id="step-2-making-the-app-ui">Step 2. Making the App UI</h2>
<p>We need to setup a basic UI to actually see our firebase code in work. I am going to explain in short here with enough details to actually carry out yourself.</p>
<p>We will be having two activity in this project. MainActivity and TodoActivity.<br />
The UI you need to make is shown in the screenshot</p>
<p><img src="http://i.imgur.com/iyLXjKU.jpg" alt="App's UI" /></p>
<p>The first activity has a recycleview and a Floating action button (FAB) in it. We will fill the recycle view with our firebase todo list and the action button takes to the TodoActivity using intent.</p>
<p>The TodoActivity has three Textviews and two EditText + a date picker in it. Pretty simple stuff.
Make a new <strong>TodoActivity.java</strong> class in your project and make the appropriate layout for it. Make sure to give ids to EditText, DatePicker to access them in activity.
Also add a FAB in this class on which we will actually save our Todo to the firebase db. Give appt id to it</p>
<h2 id="step-3-making-the-model">Step 3. Making the Model</h2>
<p>Our Todo won’t be a ArrayList or Hashmap lying around here and there in a project. We will make a proper model class for it.
Make a new <strong>Todo.java</strong> in your project and replace its content with the following</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"><span class="n">ublic</span> <span class="kd">class</span> <span class="nc">Todo</span> <span class="kd">implements</span> <span class="n">Serializable</span> <span class="o">{</span>
<span class="kd">private</span> <span class="n">String</span> <span class="n">name</span><span class="o">;</span>
<span class="kd">private</span> <span class="n">String</span> <span class="n">message</span><span class="o">;</span>
<span class="kd">private</span> <span class="n">String</span> <span class="n">date</span><span class="o">;</span>
<span class="kd">public</span> <span class="n">Todo</span><span class="o">()</span> <span class="o">{</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="n">String</span> <span class="n">getDate</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">date</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="n">setDate</span><span class="o">(</span><span class="n">String</span> <span class="n">date</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">date</span> <span class="o">=</span> <span class="n">date</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="n">String</span> <span class="n">getName</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">name</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="n">setName</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">name</span> <span class="o">=</span> <span class="n">name</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="n">String</span> <span class="n">getMessage</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">message</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="n">setMessage</span><span class="o">(</span><span class="n">String</span> <span class="n">message</span><span class="o">)</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="na">message</span> <span class="o">=</span> <span class="n">message</span><span class="o">;</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="n">HashMap</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span><span class="n">String</span><span class="o">&gt;</span> <span class="n">toFirebaseObject</span><span class="o">()</span> <span class="o">{</span>
<span class="n">HashMap</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span><span class="n">String</span><span class="o">&gt;</span> <span class="n">todo</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HashMap</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span><span class="n">String</span><span class="o">&gt;();</span>
<span class="n">todo</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"name"</span><span class="o">,</span> <span class="n">name</span><span class="o">);</span>
<span class="n">todo</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"message"</span><span class="o">,</span> <span class="n">message</span><span class="o">);</span>
<span class="n">todo</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"date"</span><span class="o">,</span> <span class="n">date</span><span class="o">);</span>
<span class="k">return</span> <span class="n">todo</span><span class="o">;</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<h2 id="step-4-back-to-understanding-how-firebase-works">Step 4. Back to understanding how Firebase works</h2>
<p>The database your app has on the firebase cloud is available on a public url like https://appname-randomIdentifer.firebaseio.com/.
Since it is public anyone can read/write to it if the url is known. To solve this the <strong>database rules</strong> section is provided where you can change the access/write rights.</p>
<p>By default firebase database require user to be authenticated before writing to the database.</p>
<h3 id="changing-database-rules">Changing Database Rules</h3>
<p>In this begginer tutorial we are going to remove the authentication required to read/write from our database. Note: <strong>You should not have this for a production app</strong>.</p>
<p>Go to the database section in the firebase console and change to the rules tab. Update the rules with the below and click publish.</p>
<figure class="highlight"><pre><code class="language-json" data-lang="json"><span class="p">{</span><span class="w">
</span><span class="nt">"rules"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nt">".read"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nt">".write"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span></code></pre></figure>
<p><img src="http://i.imgur.com/W4a6Xjm.jpg" alt="Rules" /></p>
<h2 id="database-structure">Database Structure</h2>
<p>Firebase database is actually a NoSQL
one, you won’t see any tables and where clauses in it and it is therefore <strong>a big change</strong> for many developers out there.</p>
<p>Our app has a simple Todo structure which arranged in a typical SQL database would look like.</p>
<table>
<tbody>
<tr>
<td>Name</td>
<td>Message</td>
<td>Date</td>
</tr>
<tr>
<td>First</td>
<td>Message</td>
<td>10/10/16 10:10</td>
</tr>
</tbody>
</table>
<p>But in <strong>Firebase JSON syntax</strong>, we would have to do something like this
<img src="http://i.imgur.com/rGOklwM.jpg" alt="Db structure" /></p>
<p>Each todo is uniquely identified by its key which firebase creates and our todoList is actually and array for the key <strong>todo</strong> in our db.</p>
<hr />
<h2 id="coding-actual-firebase-logic">Coding Actual Firebase Logic</h2>
<h3 id="step-5-saving-a-new-todo-in-the-firebase-db">Step 5. Saving a new Todo in the Firebase Db</h3>
<p>Now switch to TodoActivity.java and get the reference of the FAB button and set a clicklistener to it. In it we call our <strong>saveTodo</strong> method.</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"> <span class="n">FloatingActionButton</span> <span class="n">fab</span> <span class="o">=</span> <span class="o">(</span><span class="n">FloatingActionButton</span><span class="o">)</span> <span class="n">findViewById</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">id</span><span class="o">.</span><span class="na">fab</span><span class="o">);</span>
<span class="n">fab</span><span class="o">.</span><span class="na">setOnClickListener</span><span class="o">(</span><span class="k">new</span> <span class="n">View</span><span class="o">.</span><span class="na">OnClickListener</span><span class="o">()</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="n">onClick</span><span class="o">(</span><span class="n">View</span> <span class="n">view</span><span class="o">)</span> <span class="o">{</span>
<span class="n">saveTodo</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">});</span>
<span class="kt">void</span> <span class="n">saveTodo</span><span class="o">()</span> <span class="o">{</span>
<span class="c1">// first section</span>
<span class="c1">// get the data to save in our firebase db</span>
<span class="n">EditText</span> <span class="n">nameEdtText</span> <span class="o">=</span> <span class="o">(</span><span class="n">EditText</span><span class="o">)</span><span class="n">findViewById</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">id</span><span class="o">.</span><span class="na">nameEditText</span><span class="o">);</span>
<span class="n">EditText</span> <span class="n">messageEditText</span> <span class="o">=</span> <span class="o">(</span><span class="n">EditText</span><span class="o">)</span><span class="n">findViewById</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">id</span><span class="o">.</span><span class="na">messageEditText</span><span class="o">);</span>
<span class="n">DatePicker</span> <span class="n">datePicker</span> <span class="o">=</span> <span class="o">(</span><span class="n">DatePicker</span><span class="o">)</span> <span class="n">findViewById</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">id</span><span class="o">.</span><span class="na">datePicker</span><span class="o">);</span>
<span class="n">Date</span> <span class="n">date</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Date</span><span class="o">();</span>
<span class="n">date</span><span class="o">.</span><span class="na">setMonth</span><span class="o">(</span><span class="n">datePicker</span><span class="o">.</span><span class="na">getMonth</span><span class="o">());</span>
<span class="n">date</span><span class="o">.</span><span class="na">setYear</span><span class="o">(</span><span class="n">datePicker</span><span class="o">.</span><span class="na">getYear</span><span class="o">());</span>
<span class="n">date</span><span class="o">.</span><span class="na">setDate</span><span class="o">(</span><span class="n">datePicker</span><span class="o">.</span><span class="na">getDayOfMonth</span><span class="o">());</span>
<span class="n">SimpleDateFormat</span> <span class="n">format</span> <span class="o">=</span> <span class="k">new</span> <span class="n">SimpleDateFormat</span><span class="o">(</span><span class="s">"dd/MM/yyyy HH:mm"</span><span class="o">);</span>
<span class="n">String</span> <span class="n">dateString</span> <span class="o">=</span> <span class="n">format</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="n">date</span><span class="o">);</span>
<span class="c1">//make the modal object and convert it into hasmap</span>
<span class="c1">//second section</span>
<span class="c1">//save it to the firebase db</span>
<span class="n">FirebaseDatabase</span> <span class="n">database</span> <span class="o">=</span> <span class="n">FirebaseDatabase</span><span class="o">.</span><span class="na">getInstance</span><span class="o">();</span>
<span class="n">String</span> <span class="n">key</span> <span class="o">=</span> <span class="n">database</span><span class="o">.</span><span class="na">getReference</span><span class="o">(</span><span class="s">"todoList"</span><span class="o">).</span><span class="na">push</span><span class="o">().</span><span class="na">getKey</span><span class="o">();</span>
<span class="n">Todo</span> <span class="n">todo</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Todo</span><span class="o">();</span>
<span class="n">todo</span><span class="o">.</span><span class="na">setName</span><span class="o">(</span><span class="n">nameEdtText</span><span class="o">.</span><span class="na">getText</span><span class="o">().</span><span class="na">toString</span><span class="o">());</span>
<span class="n">todo</span><span class="o">.</span><span class="na">setMessage</span><span class="o">(</span><span class="n">messageEditText</span><span class="o">.</span><span class="na">getText</span><span class="o">().</span><span class="na">toString</span><span class="o">());</span>
<span class="n">todo</span><span class="o">.</span><span class="na">setDate</span><span class="o">(</span><span class="n">dateString</span><span class="o">);</span>
<span class="n">Map</span><span class="o">&lt;</span><span class="n">String</span><span class="o">,</span> <span class="n">Object</span><span class="o">&gt;</span> <span class="n">childUpdates</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HashMap</span><span class="o">&lt;&gt;();</span>
<span class="n">childUpdates</span><span class="o">.</span><span class="na">put</span><span class="o">(</span> <span class="n">key</span><span class="o">,</span> <span class="n">todo</span><span class="o">.</span><span class="na">toFirebaseObject</span><span class="o">());</span>
<span class="n">database</span><span class="o">.</span><span class="na">getReference</span><span class="o">(</span><span class="s">"todoList"</span><span class="o">).</span><span class="na">updateChildren</span><span class="o">(</span><span class="n">childUpdates</span><span class="o">,</span> <span class="k">new</span> <span class="n">DatabaseReference</span><span class="o">.</span><span class="na">CompletionListener</span><span class="o">()</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="n">onComplete</span><span class="o">(</span><span class="n">DatabaseError</span> <span class="n">databaseError</span><span class="o">,</span> <span class="n">DatabaseReference</span> <span class="n">databaseReference</span><span class="o">)</span> <span class="o">{</span>
<span class="k">if</span> <span class="o">(</span><span class="n">databaseError</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="n">finish</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">});</span>
<span class="o">}</span></code></pre></figure>
<p>Our code first section does the typical model object filling by getting the values from our view object. You can go ahead and add validation logic here if you want. The real firebase work is done in the second section.</p>
<p>In Second section , we get the database reference first and then try to get the “todoList” child in our db by calling <code class="highlighter-rouge">database.getReference("todoList")</code>.<br />
Since writing to our todoList endpoint each time will just overwrite previous values, we need to get a unique key for our new todo so that we can push it for that particular key only. We call the <code class="highlighter-rouge">push().getKey()</code> on our todoList endpoint.</p>
<p>Now we need to convert our model into a Hashmap since Firebase cannot save custom classes. <strong>String/ArrayList/Integer and Hashmap are the only supported types</strong>.
On the next line we define the childUpdate model that is for /todoList/key end point =&gt; set our dictionary object.
Calling the updateChildren performs the actual operation and we can pass a completion listener to detect any error that might have occured in the request.</p>
<p>Try running the app now and click the FAB button in MainActivity -&gt; goes to TodoActivity and in it save a new Todo. Firebase console should start showing up data that we save in the app.</p>
<h3 id="step-6-retreiving-all-our-todo-from-the-db">Step 6. Retreiving all our Todo from the DB</h3>
<p>Firebase allow you to constantly listen to a end point for any value but in our app we only want to load data once.
MainActivity code is given below :</p>
<figure class="highlight"><pre><code class="language-java" data-lang="java"> <span class="kd">public</span> <span class="kd">class</span> <span class="nc">MainActivity</span> <span class="kd">extends</span> <span class="n">AppCompatActivity</span> <span class="o">{</span>
<span class="n">RecycleAdapter</span> <span class="n">adapter</span><span class="o">;</span>
<span class="n">ArrayList</span><span class="o">&lt;</span><span class="n">Todo</span><span class="o">&gt;</span> <span class="n">todoList</span><span class="o">;</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="n">onCreate</span><span class="o">(</span><span class="n">Bundle</span> <span class="n">savedInstanceState</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">onCreate</span><span class="o">(</span><span class="n">savedInstanceState</span><span class="o">);</span>
<span class="n">setContentView</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">layout</span><span class="o">.</span><span class="na">activity_main</span><span class="o">);</span>
<span class="n">Toolbar</span> <span class="n">toolbar</span> <span class="o">=</span> <span class="o">(</span><span class="n">Toolbar</span><span class="o">)</span> <span class="n">findViewById</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">id</span><span class="o">.</span><span class="na">toolbar</span><span class="o">);</span>
<span class="n">setSupportActionBar</span><span class="o">(</span><span class="n">toolbar</span><span class="o">);</span>
<span class="n">FloatingActionButton</span> <span class="n">fab</span> <span class="o">=</span> <span class="o">(</span><span class="n">FloatingActionButton</span><span class="o">)</span> <span class="n">findViewById</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">id</span><span class="o">.</span><span class="na">fab</span><span class="o">);</span>
<span class="n">fab</span><span class="o">.</span><span class="na">setOnClickListener</span><span class="o">(</span><span class="k">new</span> <span class="n">View</span><span class="o">.</span><span class="na">OnClickListener</span><span class="o">()</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="n">onClick</span><span class="o">(</span><span class="n">View</span> <span class="n">view</span><span class="o">)</span> <span class="o">{</span>
<span class="n">Intent</span> <span class="n">newIntent</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Intent</span><span class="o">(</span><span class="n">MainActivity</span><span class="o">.</span><span class="na">this</span><span class="o">,</span><span class="n">TodoActivity</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
<span class="n">MainActivity</span><span class="o">.</span><span class="na">this</span><span class="o">.</span><span class="na">startActivity</span><span class="o">(</span><span class="n">newIntent</span><span class="o">);</span>
<span class="o">}</span>
<span class="o">});</span>
<span class="n">todoList</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ArrayList</span><span class="o">&lt;&gt;();</span>
<span class="n">RecyclerView</span> <span class="n">recyclerView</span> <span class="o">=</span> <span class="o">(</span><span class="n">RecyclerView</span><span class="o">)</span><span class="n">findViewById</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">id</span><span class="o">.</span><span class="na">myrecycleView</span><span class="o">);</span>
<span class="n">LinearLayoutManager</span> <span class="n">llm</span> <span class="o">=</span> <span class="k">new</span> <span class="n">LinearLayoutManager</span><span class="o">(</span><span class="k">this</span><span class="o">);</span>
<span class="n">recyclerView</span><span class="o">.</span><span class="na">setLayoutManager</span><span class="o">(</span><span class="n">llm</span><span class="o">);</span>
<span class="n">adapter</span> <span class="o">=</span> <span class="k">new</span> <span class="n">RecycleAdapter</span><span class="o">();</span>
<span class="n">recyclerView</span><span class="o">.</span><span class="na">setAdapter</span><span class="o">(</span><span class="n">adapter</span><span class="o">);</span>
<span class="n">adapter</span><span class="o">.</span><span class="na">notifyDataSetChanged</span><span class="o">();</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">protected</span> <span class="kt">void</span> <span class="n">onResume</span><span class="o">()</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">.</span><span class="na">onResume</span><span class="o">();</span>
<span class="n">FirebaseDatabase</span> <span class="n">database</span> <span class="o">=</span> <span class="n">FirebaseDatabase</span><span class="o">.</span><span class="na">getInstance</span><span class="o">();</span>
<span class="n">database</span><span class="o">.</span><span class="na">getReference</span><span class="o">(</span><span class="s">"todoList"</span><span class="o">).</span><span class="na">addListenerForSingleValueEvent</span><span class="o">(</span>
<span class="k">new</span> <span class="n">ValueEventListener</span><span class="o">()</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="n">onDataChange</span><span class="o">(</span><span class="n">DataSnapshot</span> <span class="n">dataSnapshot</span><span class="o">)</span> <span class="o">{</span>
<span class="n">todoList</span><span class="o">.</span><span class="na">clear</span><span class="o">();</span>
<span class="n">Log</span><span class="o">.</span><span class="na">w</span><span class="o">(</span><span class="s">"TodoApp"</span><span class="o">,</span> <span class="s">"getUser:onCancelled "</span> <span class="o">+</span> <span class="n">dataSnapshot</span><span class="o">.</span><span class="na">toString</span><span class="o">());</span>
<span class="n">Log</span><span class="o">.</span><span class="na">w</span><span class="o">(</span><span class="s">"TodoApp"</span><span class="o">,</span> <span class="s">"count = "</span> <span class="o">+</span> <span class="n">String</span><span class="o">.</span><span class="na">valueOf</span><span class="o">(</span><span class="n">dataSnapshot</span><span class="o">.</span><span class="na">getChildrenCount</span><span class="o">())</span> <span class="o">+</span> <span class="s">" values "</span> <span class="o">+</span> <span class="n">dataSnapshot</span><span class="o">.</span><span class="na">getKey</span><span class="o">());</span>
<span class="k">for</span> <span class="o">(</span><span class="n">DataSnapshot</span> <span class="n">data</span> <span class="o">:</span> <span class="n">dataSnapshot</span><span class="o">.</span><span class="na">getChildren</span><span class="o">())</span> <span class="o">{</span>
<span class="n">Todo</span> <span class="n">todo</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="na">getValue</span><span class="o">(</span><span class="n">Todo</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
<span class="n">todoList</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">todo</span><span class="o">);</span>
<span class="o">}</span>
<span class="n">adapter</span><span class="o">.</span><span class="na">notifyDataSetChanged</span><span class="o">();</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="n">onCancelled</span><span class="o">(</span><span class="n">DatabaseError</span> <span class="n">databaseError</span><span class="o">)</span> <span class="o">{</span>
<span class="n">Log</span><span class="o">.</span><span class="na">w</span><span class="o">(</span><span class="s">"TodoApp"</span><span class="o">,</span> <span class="s">"getUser:onCancelled"</span><span class="o">,</span> <span class="n">databaseError</span><span class="o">.</span><span class="na">toException</span><span class="o">());</span>
<span class="o">}</span>
<span class="o">});</span>
<span class="o">}</span>
<span class="kd">private</span> <span class="kd">class</span> <span class="nc">RecycleAdapter</span> <span class="kd">extends</span> <span class="n">RecyclerView</span><span class="o">.</span><span class="na">Adapter</span> <span class="o">{</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">int</span> <span class="n">getItemCount</span><span class="o">()</span> <span class="o">{</span>
<span class="k">return</span> <span class="n">todoList</span><span class="o">.</span><span class="na">size</span><span class="o">();</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="n">RecyclerView</span><span class="o">.</span><span class="na">ViewHolder</span> <span class="n">onCreateViewHolder</span><span class="o">(</span><span class="n">ViewGroup</span> <span class="n">parent</span><span class="o">,</span> <span class="kt">int</span> <span class="n">viewType</span><span class="o">)</span> <span class="o">{</span>
<span class="n">View</span> <span class="n">v</span> <span class="o">=</span> <span class="n">LayoutInflater</span><span class="o">.</span><span class="na">from</span><span class="o">(</span><span class="n">parent</span><span class="o">.</span><span class="na">getContext</span><span class="o">()).</span><span class="na">inflate</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">layout</span><span class="o">.</span><span class="na">todo_item</span><span class="o">,</span> <span class="n">parent</span><span class="o">,</span> <span class="kc">false</span><span class="o">);</span>
<span class="n">SimpleItemViewHolder</span> <span class="n">pvh</span> <span class="o">=</span> <span class="k">new</span> <span class="n">SimpleItemViewHolder</span><span class="o">(</span><span class="n">v</span><span class="o">);</span>
<span class="k">return</span> <span class="n">pvh</span><span class="o">;</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="n">onBindViewHolder</span><span class="o">(</span><span class="n">RecyclerView</span><span class="o">.</span><span class="na">ViewHolder</span> <span class="n">holder</span><span class="o">,</span> <span class="kt">int</span> <span class="n">position</span><span class="o">)</span> <span class="o">{</span>
<span class="n">SimpleItemViewHolder</span> <span class="n">viewHolder</span> <span class="o">=</span> <span class="o">(</span><span class="n">SimpleItemViewHolder</span><span class="o">)</span> <span class="n">holder</span><span class="o">;</span>
<span class="n">viewHolder</span><span class="o">.</span><span class="na">position</span> <span class="o">=</span> <span class="n">position</span><span class="o">;</span>
<span class="n">Todo</span> <span class="n">todo</span> <span class="o">=</span> <span class="n">todoList</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">position</span><span class="o">);</span>
<span class="o">((</span><span class="n">SimpleItemViewHolder</span><span class="o">)</span> <span class="n">holder</span><span class="o">).</span><span class="na">title</span><span class="o">.</span><span class="na">setText</span><span class="o">(</span><span class="n">todo</span><span class="o">.</span><span class="na">getName</span><span class="o">());</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">final</span> <span class="kd">class</span> <span class="nc">SimpleItemViewHolder</span> <span class="kd">extends</span> <span class="n">RecyclerView</span><span class="o">.</span><span class="na">ViewHolder</span> <span class="kd">implements</span> <span class="n">View</span><span class="o">.</span><span class="na">OnClickListener</span> <span class="o">{</span>
<span class="n">TextView</span> <span class="n">title</span><span class="o">;</span>
<span class="kd">public</span> <span class="kt">int</span> <span class="n">position</span><span class="o">;</span>
<span class="kd">public</span> <span class="n">SimpleItemViewHolder</span><span class="o">(</span><span class="n">View</span> <span class="n">itemView</span><span class="o">)</span> <span class="o">{</span>
<span class="kd">super</span><span class="o">(</span><span class="n">itemView</span><span class="o">);</span>
<span class="n">itemView</span><span class="o">.</span><span class="na">setOnClickListener</span><span class="o">(</span><span class="k">this</span><span class="o">);</span>
<span class="n">title</span> <span class="o">=</span> <span class="o">(</span><span class="n">TextView</span><span class="o">)</span> <span class="n">itemView</span><span class="o">.</span><span class="na">findViewById</span><span class="o">(</span><span class="n">R</span><span class="o">.</span><span class="na">id</span><span class="o">.</span><span class="na">myTextView</span><span class="o">);</span>
<span class="o">}</span>
<span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="n">onClick</span><span class="o">(</span><span class="n">View</span> <span class="n">view</span><span class="o">)</span> <span class="o">{</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span></code></pre></figure>
<p>First we declare a ArrayList which will hold all our Todo model objects. Next we call the loadData method in our <code class="highlighter-rouge">onResume</code> method so that our data is refreshed everytime MainActivity is launched as well as when we come back to the view after saving a new Todo.
In <strong>loadData</strong> we get the reference to our <strong>todoList</strong> endpoint and call the <strong>addListenerForSingleValueEvent</strong> method since that observes the value event only one and is not kept in memory all the time listening for any real time changes in our end point. In the closure <strong>dataSnapshot.value</strong> contains the value of that endpoint.</p>
<p>If you observe the db in the console; each todo is uniquely identified by a key therefore in our case the snapshot.value actually contains children with as much number of Todo. If our model is a <strong>Java Pojo</strong> we can cast it into a <code class="highlighter-rouge">Todo</code> object using <strong>data.getValue(Todo.class);</strong>. snapshot will contain all our todo so we enumberate its children which containe name,message and date of our Todo, we fill up our model with that and add it to the array. In the end we call our recycleview adapter <strong>notifyDataSetChanged</strong> to show the list of Todo in our UI.</p>
<h3 id="step-7-viewing-existing-todo">Step 7. Viewing existing Todo</h3>
<p>We do have our todo being retrieved and the name being shown in recycleview but clicking one should go to the <strong>TodoActivity</strong> and show all details right ? So in the <em>onClick</em> method in your ViewHolder class</p>
<figure class="highlight"><pre><code class="language-swift" data-lang="swift"> <span class="kd">@Override</span>
<span class="kd">public</span> <span class="n">void</span> <span class="nf">onClick</span><span class="p">(</span><span class="kt">View</span> <span class="n">view</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">Intent</span> <span class="n">newIntent</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">Intent</span><span class="p">(</span><span class="kt">MainActivity</span><span class="o">.</span><span class="n">this</span><span class="p">,</span><span class="kt">TodoActivity</span><span class="o">.</span><span class="kd">class</span><span class="p">);</span>
<span class="n">newIntent</span><span class="o">.</span><span class="nf">putExtra</span><span class="p">(</span><span class="s">"todo"</span><span class="p">,</span> <span class="n">todoList</span><span class="o">.</span><span class="nf">get</span><span class="p">(</span><span class="n">position</span><span class="p">));</span>
<span class="kt">MainActivity</span><span class="o">.</span><span class="n">this</span><span class="o">.</span><span class="nf">startActivity</span><span class="p">(</span><span class="n">newIntent</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>
<p>Real simple code right there. Now you need to show those details in the outlets in your TodoActivity class. Update its <strong>onCreate</strong> with the following code</p>
<figure class="highlight"><pre><code class="language-swift" data-lang="swift"> <span class="c1">// previous onCreate code</span>
<span class="k">if</span> <span class="p">(</span><span class="nf">getIntent</span><span class="p">()</span><span class="o">.</span><span class="nf">getExtras</span><span class="p">()</span> <span class="o">!=</span> <span class="n">null</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">Bundle</span> <span class="n">extras</span> <span class="o">=</span> <span class="nf">getIntent</span><span class="p">()</span><span class="o">.</span><span class="nf">getExtras</span><span class="p">();</span>
<span class="kt">Todo</span> <span class="n">todo</span> <span class="o">=</span> <span class="p">(</span><span class="kt">Todo</span><span class="p">)</span><span class="n">extras</span><span class="o">.</span><span class="nf">get</span><span class="p">(</span><span class="s">"todo"</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">todo</span> <span class="o">!=</span> <span class="n">null</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">EditText</span> <span class="n">nameEdtText</span> <span class="o">=</span> <span class="p">(</span><span class="kt">EditText</span><span class="p">)</span><span class="nf">findViewById</span><span class="p">(</span><span class="kt">R</span><span class="o">.</span><span class="n">id</span><span class="o">.</span><span class="n">nameEditText</span><span class="p">);</span>
<span class="kt">EditText</span> <span class="n">messageEditText</span> <span class="o">=</span> <span class="p">(</span><span class="kt">EditText</span><span class="p">)</span><span class="nf">findViewById</span><span class="p">(</span><span class="kt">R</span><span class="o">.</span><span class="n">id</span><span class="o">.</span><span class="n">messageEditText</span><span class="p">);</span>
<span class="kt">DatePicker</span> <span class="n">datePicker</span> <span class="o">=</span> <span class="p">(</span><span class="kt">DatePicker</span><span class="p">)</span> <span class="nf">findViewById</span><span class="p">(</span><span class="kt">R</span><span class="o">.</span><span class="n">id</span><span class="o">.</span><span class="n">datePicker</span><span class="p">);</span>
<span class="n">nameEdtText</span><span class="o">.</span><span class="nf">setText</span><span class="p">(</span><span class="n">todo</span><span class="o">.</span><span class="nf">getName</span><span class="p">());</span>
<span class="n">messageEditText</span><span class="o">.</span><span class="nf">setText</span><span class="p">(</span><span class="n">todo</span><span class="o">.</span><span class="nf">getMessage</span><span class="p">());</span>
<span class="kt">SimpleDateFormat</span> <span class="n">format</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">SimpleDateFormat</span><span class="p">(</span><span class="s">"dd/MM/yyyy HH:mm"</span><span class="p">);</span>
<span class="k">try</span> <span class="p">{</span>
<span class="kt">Date</span> <span class="n">date</span> <span class="o">=</span> <span class="n">format</span><span class="o">.</span><span class="nf">parse</span><span class="p">(</span><span class="n">todo</span><span class="o">.</span><span class="nf">getDate</span><span class="p">());</span>
<span class="n">datePicker</span><span class="o">.</span><span class="nf">updateDate</span><span class="p">(</span><span class="n">date</span><span class="o">.</span><span class="nf">getYear</span><span class="p">(),</span> <span class="n">date</span><span class="o">.</span><span class="nf">getMonth</span><span class="p">(),</span> <span class="n">date</span><span class="o">.</span><span class="nf">getDate</span><span class="p">());</span>
<span class="p">}</span> <span class="nf">catch</span> <span class="p">(</span><span class="kt">ParseException</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
<span class="n">e</span><span class="o">.</span><span class="nf">printStackTrace</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></figure>
<p>That’s it to have our todo app functioning on our firebase database :).</p>
<h2 id="conclusion">Conclusion</h2>
<p><strong>Thank you</strong> for reading this far. For any questions you are welcome to ask in our chat room.</p>
<h2 id="next-steps">Next Steps</h2>
<p>Please take a look at our other <a href="../../tutorials">tutorials</a> :)</p>
</description>
<pubDate>Wed, 01 Jun 2016 00:00:00 +0530</pubDate>
<link>http://shubhank101.github.io/iOSAndroidChaosOverFlow/2016/06/todo-app-with-firebase-part-1-(Android)</link>
<guid isPermaLink="true">http://shubhank101.github.io/iOSAndroidChaosOverFlow/2016/06/todo-app-with-firebase-part-1-(Android)</guid>
<category>firebase</category>
<category>android</category>
<category>java</category>
<category>tutorial</category>
<category>todo app</category>
<category>lessons</category>
</item>
<item>
<title>Todo App With Firebase Part 1 (xcode)</title>
<description><blockquote>
<p>This tutorial assumes you are familiar with basics of iOS development including Xcode, swift and cocoapods.</p>
</blockquote>
<h1 id="what-is-firebase">What is Firebase?</h1>
<p><img src="https://1.bp.blogspot.com/-YIfQT6q8ZM4/Vzyq5z1B8HI/AAAAAAAAAAc/UmWSSMLKtKgtH7CACElUp12zXkrPK5UoACLcB/s1600/image00.png" alt="Firebase logo" /></p>
<p><strong>Firebase</strong> is a multi purpose sdk which can be used to integrate push notifications in your app, app analytics and a whole lot of other features which you can review on its site.</p>
<p>We are going to use <strong>Firebase Realtime Database</strong> here to develop a simple To-do app.</p>
<h2 id="step-1-setting-up-xcode-project">Step 1. Setting up Xcode Project</h2>
<p>Create a new swift Xcode Project and name it TodoApp.
Now note down the <strong>bundle id</strong>, we will need it to make the <code class="highlighter-rouge">GoogleService-Info</code> plist file.</p>
<p>Head over to <a href="https://console.firebase.google.com/">Firebase console</a> and click <strong>Create New Project</strong>. Enter TodoApp as the name project and click create project. You will be redirected to a screen like this</p>
<p><img src="http://i.imgur.com/41Rq8Ij.jpg" alt="Firebase Console" /></p>
<p>Click Add firebase to your iOS project and in the popup - <strong>Enter your project bundle id</strong></p>
<p><img src="http://i.imgur.com/gwUb9E1.jpg" alt="Bundle id popup" /></p>
<p>Press Add app and now you will get the <strong>GoogleService-Info.plist</strong> downloaded automatically. Now keep pressing continue to finish the integration steps and get back to the project.</p>
<p>Drag the plist you downloaded into your project root (where .xcodeProj file is). The plist file actually includes all the relevant settings for the firebase app including the firebase database url for your app.</p>
<h3 id="setup-pods">Setup Pods</h3>
<p>Open a terminal and execute <strong>pod init</strong> in your project directory. Open the pod file in text editor or in Xcode and add these pods to the todo target</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml">pod 'Firebase'
pod 'Firebase/Database'</code></pre></figure>
<p>Run <strong>pod install</strong> in terminal and once completed open the <strong>.xcworkspace</strong> file to open the project.</p>
<h2 id="step-2-making-the-app-ui">Step 2. Making the App UI</h2>
<p>We need to setup a basic UI to actually see our firebase code in work. I am going to explain in short here with enough details to actually carry out yourself.</p>
<p>Embed the initial view controller in a navigation controller (this gives us the navigation stack). Now add another view controller and set its storyboard id to <strong>ToDoVC</strong>.
The UI you need to make is shown in the screenshot</p>
<p><img src="http://i.imgur.com/eN1Y4qT.jpg" alt="App's UI" /></p>
<p>The first VC has a TableView and a UIBarButtonItem in it. TableView has a dynamic prototype cell and i have given cellIdentifier as <strong>ToDoCell</strong>. Make sure to make the tableview outlet and set its delegate and data source to your VC class.</p>
<p>The bar button just segues to the TodoViewController (our second VC in the screen).</p>
<p>The TodoViewController has three labels and two textfields + a date picker in it. Pretty simple stuff.
Make a new <strong>TodoViewController.swift</strong> class in your project and assign it to the VC. Then make all the textfield and date picker outlets.
Also add a Done/Save barbutton item in this class on which we will actually save our Todo to the firebase db. Make the appt <strong>IBAction</strong> for it.</p>
<h2 id="step-3-making-the-model">Step 3. Making the Model</h2>
<p>Our Todo won’t be a Array or Dictionary lying around here and there in a project. We will make a proper model class for it.
Make a new <strong>Todo.swift</strong> in your project and replace its content with the following</p>
<figure class="highlight"><pre><code class="language-swift" data-lang="swift"><span class="kd">import</span> <span class="kt">UIKit</span>
<span class="kd">class</span> <span class="kt">Todo</span><span class="p">:</span> <span class="kt">NSObject</span> <span class="p">{</span>
<span class="k">var</span> <span class="nv">name</span> <span class="p">:</span><span class="kt">String</span><span class="p">?</span>
<span class="k">var</span> <span class="nv">message</span><span class="p">:</span> <span class="kt">String</span><span class="p">?</span>
<span class="k">var</span> <span class="nv">reminderDate</span><span class="p">:</span> <span class="kt">String</span><span class="p">?</span>
<span class="c1">// id which is set from firebase to uniquely identify it</span>
<span class="k">var</span> <span class="nv">uniqueId</span><span class="p">:</span><span class="kt">String</span><span class="p">?</span>
<span class="p">}</span></code></pre></figure>
<h2 id="step-4-back-to-understanding-how-firebase-works">Step 4. Back to understanding how Firebase works</h2>
<p>The database your app has on the firebase cloud is available on a public url like https://appname-randomIdentifer.firebaseio.com/.
Since it is public anyone can read/write to it if the url is known. To solve this the <strong>database rules</strong> section is provided where you can change the access/write rights.</p>
<p>By default firebase database require user to be authenticated before writing to the database.</p>
<h3 id="changing-database-rules">Changing Database Rules</h3>
<p>In this begginer tutorial we are going to remove the authentication required to read/write from our database. Note: <strong>You should not have this for a production app</strong>.</p>
<p>Go to the database section in the firebase console and change to the rules tab. Update the rules with the below and click publish.</p>
<figure class="highlight"><pre><code class="language-json" data-lang="json"><span class="p">{</span><span class="w">
</span><span class="nt">"rules"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nt">".read"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nt">".write"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span></code></pre></figure>
<p><img src="http://i.imgur.com/W4a6Xjm.jpg" alt="Rules" /></p>
<h2 id="database-structure">Database Structure</h2>
<p>Firebase database is actually a NoSQL
one, you won’t see any tables and where clauses in it and it is therefore <strong>a big change</strong> for many developers out there.</p>
<p>Our app has a simple Todo structure which arranged in a typical SQL database would look like.</p>
<table>
<tbody>
<tr>
<td>Name</td>
<td>Message</td>
<td>Date</td>
</tr>
<tr>
<td>First</td>
<td>Message</td>
<td>10/10/16 10:10</td>
</tr>
</tbody>