Commit 3722fdfc by Anand.suthar

Firebase chat implementation

parent 4e4ed4e5
......@@ -56,6 +56,7 @@
B08BEE7B20F0935E00E972D3 /* Follower.swift in Sources */ = {isa = PBXBuildFile; fileRef = B08BEE7A20F0935E00E972D3 /* Follower.swift */; };
B08BEE7D20F0960000E972D3 /* FollowerExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = B08BEE7C20F0960000E972D3 /* FollowerExt.swift */; };
B08C9A7920F4EC5F00E0BCF5 /* EditResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B08C9A7820F4EC5F00E0BCF5 /* EditResult.swift */; };
B091CD712119A46B00E270BF /* Chat.swift in Sources */ = {isa = PBXBuildFile; fileRef = B091CD702119A46B00E270BF /* Chat.swift */; };
B09212A620B8052400798423 /* DateExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = B09212A520B8052400798423 /* DateExt.swift */; };
B09212A820B8053B00798423 /* NotificationNameExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = B09212A720B8053B00798423 /* NotificationNameExt.swift */; };
B09212AA20B8054A00798423 /* RealmExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = B09212A920B8054A00798423 /* RealmExt.swift */; };
......@@ -69,6 +70,7 @@
B0922C7120F6446B00E9F7FD /* CorporateCultureExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0922C7020F6446B00E9F7FD /* CorporateCultureExt.swift */; };
B092806220F3A4CB00C87648 /* RecommendProduct.swift in Sources */ = {isa = PBXBuildFile; fileRef = B092806120F3A4CB00C87648 /* RecommendProduct.swift */; };
B092806C20F3A4D600C87648 /* RecommendProductExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = B092806B20F3A4D600C87648 /* RecommendProductExt.swift */; };
B093FF8C2119975C001DCA11 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = B093FF832119975B001DCA11 /* GoogleService-Info.plist */; };
B09A64BF20F7877E00222611 /* NavigationBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B09A64BE20F7877E00222611 /* NavigationBarView.swift */; };
B0A0827920EF924100F78AEC /* UserSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0A0827820EF924100F78AEC /* UserSettings.swift */; };
B0B9025320B6B36100AE834E /* MyIncomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0B9025220B6B36100AE834E /* MyIncomeViewController.swift */; };
......@@ -558,6 +560,7 @@
B08BEE7A20F0935E00E972D3 /* Follower.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Follower.swift; sourceTree = "<group>"; };
B08BEE7C20F0960000E972D3 /* FollowerExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowerExt.swift; sourceTree = "<group>"; };
B08C9A7820F4EC5F00E0BCF5 /* EditResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditResult.swift; sourceTree = "<group>"; };
B091CD702119A46B00E270BF /* Chat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Chat.swift; sourceTree = "<group>"; };
B09212A520B8052400798423 /* DateExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateExt.swift; sourceTree = "<group>"; };
B09212A720B8053B00798423 /* NotificationNameExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationNameExt.swift; sourceTree = "<group>"; };
B09212A920B8054A00798423 /* RealmExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealmExt.swift; sourceTree = "<group>"; };
......@@ -572,6 +575,7 @@
B0922C7020F6446B00E9F7FD /* CorporateCultureExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CorporateCultureExt.swift; sourceTree = "<group>"; };
B092806120F3A4CB00C87648 /* RecommendProduct.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendProduct.swift; sourceTree = "<group>"; };
B092806B20F3A4D600C87648 /* RecommendProductExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendProductExt.swift; sourceTree = "<group>"; };
B093FF832119975B001DCA11 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
B09A64BE20F7877E00222611 /* NavigationBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBarView.swift; sourceTree = "<group>"; };
B0A0827820EF924100F78AEC /* UserSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSettings.swift; sourceTree = "<group>"; };
B0B9025220B6B36100AE834E /* MyIncomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyIncomeViewController.swift; sourceTree = "<group>"; };
......@@ -946,6 +950,7 @@
B01B216D20EF877A002AC8D5 /* Model */ = {
isa = PBXGroup;
children = (
B091CD672119A43F00E270BF /* FireBaseChat */,
B038371420F37F2F00B68870 /* Appointment */,
B0F371E320EFB08D000F92D2 /* Home */,
B08BEE7920F0933600E972D3 /* Me */,
......@@ -1136,6 +1141,14 @@
path = Me;
sourceTree = "<group>";
};
B091CD672119A43F00E270BF /* FireBaseChat */ = {
isa = PBXGroup;
children = (
B091CD702119A46B00E270BF /* Chat.swift */,
);
path = FireBaseChat;
sourceTree = "<group>";
};
B09212A420B8050E00798423 /* Extensions */ = {
isa = PBXGroup;
children = (
......@@ -1295,6 +1308,7 @@
EC04CD3C2052CC0100B425BB /* Assets.xcassets */,
B024385020B52EF5007D12AE /* Fengshui.xcassets */,
EC04CD412052CC0100B425BB /* Info.plist */,
B093FF832119975B001DCA11 /* GoogleService-Info.plist */,
);
path = Bhagyashree;
sourceTree = "<group>";
......@@ -2046,6 +2060,7 @@
EC04CE782052CDE700B425BB /* CompareProductAttributeValueCollectionView.xib in Resources */,
EC04CEAC2052CE2C00B425BB /* EmptyNewAddress.xib in Resources */,
EC04CD3D2052CC0100B425BB /* Assets.xcassets in Resources */,
B093FF8C2119975C001DCA11 /* GoogleService-Info.plist in Resources */,
B06CB32920F628DF007FD838 /* hi.json in Resources */,
EC04CEE62052CE7500B425BB /* WishListTableViewCell.xib in Resources */,
EC04CD5C2052CC6000B425BB /* CreditMemoCommentCell.xib in Resources */,
......@@ -2164,6 +2179,8 @@
"${SRCROOT}/Pods/Target Support Files/Pods-Bhagyashree/Pods-Bhagyashree-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/BufferSlider/BufferSlider.framework",
"${BUILT_PRODUCTS_DIR}/EasyToast/EasyToast.framework",
"${BUILT_PRODUCTS_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework",
"${BUILT_PRODUCTS_DIR}/GoogleToolboxForMac/GoogleToolboxForMac.framework",
"${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework",
"${BUILT_PRODUCTS_DIR}/ImageSlideshow/ImageSlideshow.framework",
"${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework",
......@@ -2175,11 +2192,15 @@
"${BUILT_PRODUCTS_DIR}/SwiftDate/SwiftDate.framework",
"${BUILT_PRODUCTS_DIR}/TimeAgoInWords/TimeAgoInWords.framework",
"${BUILT_PRODUCTS_DIR}/WMPageController/WMPageController.framework",
"${BUILT_PRODUCTS_DIR}/leveldb-library/leveldb.framework",
"${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BufferSlider.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/EasyToast.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMSessionFetcher.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleToolboxForMac.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManagerSwift.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ImageSlideshow.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Kingfisher.framework",
......@@ -2191,6 +2212,8 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftDate.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TimeAgoInWords.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/WMPageController.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/leveldb.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
......@@ -2217,6 +2240,7 @@
EC04CED62052CE5800B425BB /* CustomerOrderDetailsModel.swift in Sources */,
EC04CEE12052CE6700B425BB /* MyOrdersModel.swift in Sources */,
EC04CFCD2052CF2A00B425BB /* GradientArcView.swift in Sources */,
B091CD712119A46B00E270BF /* Chat.swift in Sources */,
EC04CDE52052CD5500B425BB /* MyTransactionFilterController.swift in Sources */,
EC04CE152052CDA300B425BB /* SellerDashBoardReportCell.swift in Sources */,
B060D85220F4BA1700F8B71E /* Withdraw.swift in Sources */,
......@@ -2666,7 +2690,7 @@
DEVELOPMENT_TEAM = S5AR757G56;
INFOPLIST_FILE = Bhagyashree/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.gdi.yuanzhongsiu-seller";
PRODUCT_BUNDLE_IDENTIFIER = "com.gdi.yuanzhongsiu-seller-dev";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
......@@ -2690,7 +2714,7 @@
DEVELOPMENT_TEAM = S5AR757G56;
INFOPLIST_FILE = Bhagyashree/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.gdi.yuanzhongsiu-seller";
PRODUCT_BUNDLE_IDENTIFIER = "com.gdi.yuanzhongsiu-seller-dev";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
......
......@@ -7,7 +7,7 @@
<key>Bhagyashree.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>22</integer>
<integer>30</integer>
</dict>
</dict>
</dict>
......
......@@ -15,24 +15,8 @@
endingColumnNumber = "9223372036854775807"
startingLineNumber = "64"
endingLineNumber = "64"
landmarkName = "unknown"
landmarkType = "0">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Bhagyashree/Sunarc/Other/HTTP/HTTP.swift"
timestampString = "553782528.911063"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "121"
endingLineNumber = "121"
landmarkName = "unknown"
landmarkType = "0">
landmarkName = "connectWithRequestObject(api:parameters:method:contentType:indicator:success:failure:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
......@@ -47,8 +31,8 @@
endingColumnNumber = "9223372036854775807"
startingLineNumber = "76"
endingLineNumber = "76"
landmarkName = "unknown"
landmarkType = "0">
landmarkName = "connectWithRequestObject(api:parameters:method:contentType:indicator:success:failure:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
......@@ -65,22 +49,68 @@
endingLineNumber = "22"
landmarkName = "unknown"
landmarkType = "0">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Bhagyashree/Sunarc/Controller/Me/CorporateCultureViewController.swift"
timestampString = "553786746.458065"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "56"
endingLineNumber = "56"
landmarkName = "unknown"
landmarkType = "0">
<Locations>
<Location
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "Bhagyashree.CorporateCultureViewController.slideshow.getter : Swift.ImplicitlyUnwrappedOptional&lt;ImageSlideshow.ImageSlideshow&gt;"
moduleName = "Bhagyashree"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/sunarcmac/Documents/Futurecommerce/Fengshui-Seller-iOS/Bhagyashree/Sunarc/Controller/Me/CorporateCultureViewController.swift"
timestampString = "555406002.442651"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "22"
endingLineNumber = "22"
offsetFromSymbolStart = "104">
</Location>
<Location
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "Bhagyashree.CorporateCultureViewController.slideshow.setter : Swift.ImplicitlyUnwrappedOptional&lt;ImageSlideshow.ImageSlideshow&gt;"
moduleName = "Bhagyashree"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/sunarcmac/Documents/Futurecommerce/Fengshui-Seller-iOS/Bhagyashree/Sunarc/Controller/Me/CorporateCultureViewController.swift"
timestampString = "555406002.446547"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "22"
endingLineNumber = "22"
offsetFromSymbolStart = "120">
</Location>
<Location
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "Bhagyashree.CorporateCultureViewController.init(nibName: Swift.Optional&lt;Swift.String&gt;, bundle: Swift.Optional&lt;__ObjC.Bundle&gt;) -&gt; Bhagyashree.CorporateCultureViewController"
moduleName = "Bhagyashree"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/sunarcmac/Documents/Futurecommerce/Fengshui-Seller-iOS/Bhagyashree/Sunarc/Controller/Me/CorporateCultureViewController.swift"
timestampString = "555406002.451793"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "22"
endingLineNumber = "22"
offsetFromSymbolStart = "424">
</Location>
<Location
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "Bhagyashree.CorporateCultureViewController.init(coder: __ObjC.NSCoder) -&gt; Swift.Optional&lt;Bhagyashree.CorporateCultureViewController&gt;"
moduleName = "Bhagyashree"
usesParentBreakpointCondition = "Yes"
urlString = "file:///Users/sunarcmac/Documents/Futurecommerce/Fengshui-Seller-iOS/Bhagyashree/Sunarc/Controller/Me/CorporateCultureViewController.swift"
timestampString = "555406002.455837"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "22"
endingLineNumber = "22"
offsetFromSymbolStart = "380">
</Location>
</Locations>
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
......
......@@ -10,6 +10,8 @@ import UIKit
import Fabric
import Crashlytics
import UserNotifications
import Firebase
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
......@@ -25,6 +27,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
UIApplication.shared.statusBarStyle = .lightContent
Fabric.with([Crashlytics.self])
FirebaseApp.configure()
// let backImage = UIImage(named: "ic_back")?.withRenderingMode(.alwaysOriginal)
// UINavigationBar.appearance().backIndicatorImage = backImage
// UINavigationBar.appearance().backIndicatorTransitionMaskImage = backImage
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AD_UNIT_ID_FOR_BANNER_TEST</key>
<string>ca-app-pub-3940256099942544/2934735716</string>
<key>AD_UNIT_ID_FOR_INTERSTITIAL_TEST</key>
<string>ca-app-pub-3940256099942544/4411468910</string>
<key>CLIENT_ID</key>
<string>948213756039-ctnseb32i76tvtuc8kvn3c6l09dpr9qf.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.948213756039-ctnseb32i76tvtuc8kvn3c6l09dpr9qf</string>
<key>API_KEY</key>
<string>AIzaSyDJqRanYPwGFARc6XQ5GUC5pUuBDgJm0D4</string>
<key>GCM_SENDER_ID</key>
<string>948213756039</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.gdi.yuanzhongsiu-seller</string>
<key>PROJECT_ID</key>
<string>fengshui-9263b</string>
<key>STORAGE_BUCKET</key>
<string>fengshui-9263b.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<true></true>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<false></false>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:948213756039:ios:84a8dd99e8502ac3</string>
<key>DATABASE_URL</key>
<string>https://fengshui-9263b.firebaseio.com</string>
</dict>
</plist>
\ No newline at end of file
......@@ -9,12 +9,14 @@
import UIKit
import Kingfisher
import MJRefresh
import FirebaseDatabase
class OngoingEnquiryViewController: BaseViewController {
@IBOutlet var tblEnquires: UITableView!
var enquiry = Enquiry()
var footerForLoading: MJRefreshAutoNormalFooter!
var ref = Database.database().reference()
override func viewDidLoad() {
super.viewDidLoad()
......@@ -86,9 +88,7 @@ extension OngoingEnquiryViewController: UITableViewDataSource, UITableViewDelega
let ongoingEnquiry = enquiry.enquiries[indexPath.row]
let ongoinCell = tableView.dequeueReusableCell(withIdentifier: "ongoing") as! OngoingEnquiryCell
ongoinCell.lblBadge.text = "1"
ongoinCell.lblTime.text = ongoingEnquiry.bookingTill
ongoinCell.lblMessageDesc.text = "replaced with firbase msg"
ongoinCell.lblCustName.text = ongoingEnquiry.customerName
if let profileImage = ongoingEnquiry.customerProfileImage {
......@@ -98,7 +98,7 @@ extension OngoingEnquiryViewController: UITableViewDataSource, UITableViewDelega
ongoinCell.updateUI()
ongoinCell.getFireBaseData()
return ongoinCell
}
......@@ -117,8 +117,65 @@ class OngoingEnquiryCell: UITableViewCell {
@IBOutlet var lblTime: UILabel!
@IBOutlet var lblBadge: UILabel!
func updateUI() {
override func layoutSubviews() {
lblBadge.layer.cornerRadius = lblBadge.frame.size.height/2
// imgCustomer.layer.cornerRadius = imgCustomer.frame.size.width/2
}
func getTimeFromFirebaseTimeStamp(time: TimeInterval) {
let timeInHoursAgo = Date.pcTimeAgoFrom(Date(timeIntervalSince1970: time/1000))
self.lblTime.text = "\(timeInHoursAgo)"
}
func getFireBaseData() {
let ref = Database.database().reference().child("20") // replace 20 with orderid
ref.queryOrdered(byChild: "timestamp") .observe(DataEventType.value, with: { (snapshot) in
if let chatsJSON = snapshot.value as? [String: AnyObject] {
var chats = [Chat]()
for json in chatsJSON {
if let object = json.value as? [String: Any] {
let chat = Chat(json: object, chatId: json.key)
chats.append(chat)
}
}
chats = chats.sorted(by: { $0.timeStamp < $1.timeStamp })
var unreadCount = 0
var lastUnreadMSG = ""
var lastTimeStamp: TimeInterval = 0
for chat in chats {
if chat.name == "Customer" {
if chat.readStatus == "unread" {
unreadCount += 1
lastUnreadMSG = chat.msg
lastTimeStamp = chat.timeStamp
}
}
}
if unreadCount == 0 {
self.lblBadge.isHidden = true
self.lblMessageDesc.isHidden = true
self.lblTime.isHidden = true
} else {
self.lblBadge.isHidden = false
self.lblMessageDesc.isHidden = false
self.lblTime.isHidden = false
self.lblBadge.text = "\(unreadCount)"
self.lblMessageDesc.text = lastUnreadMSG
self.getTimeFromFirebaseTimeStamp(time: lastTimeStamp)
}
}
})
}
}
......@@ -7,17 +7,58 @@
//
import UIKit
import FirebaseDatabase
class OnlineEnquiryViewController: UIViewController {
@IBOutlet var tblChat: UITableView!
@IBOutlet var txtComment: UITextView!
@IBOutlet var lblPlaceHolder: UILabel!
@IBOutlet weak var commentViewHeight: NSLayoutConstraint!
@IBOutlet var btnSend: UIButton!
var ref = Database.database().reference()
var chats = [Chat]()
override func viewDidLoad() {
super.viewDidLoad()
ref = Database.database().reference().child("20") // replace 20 with orderid
ref.queryOrdered(byChild: "timestamp") .observe(DataEventType.value, with: { (snapshot) in
self.chats = [Chat]()
if let chatsJSON = snapshot.value as? [String: AnyObject] {
self.chats = [Chat]()
for json in chatsJSON {
if let object = json.value as? [String: Any] {
let chat = Chat(json: object, chatId: json.key)
self.chats.append(chat)
}
}
self.chats = self.chats.sorted(by: { $0.timeStamp < $1.timeStamp })
self.tblChat.reloadData()
self.makeAllMSGAsRead()
}
})
}
func makeAllMSGAsRead() {
for chat in chats {
if chat.name == "Customer" {
if chat.readStatus == "unread" {
ref.child(chat.chatId).updateChildValues(["status": "read"])
}
}
}
}
}
......@@ -25,6 +66,21 @@ class OnlineEnquiryViewController: UIViewController {
extension OnlineEnquiryViewController {
@IBAction func sendMessage() {
if txtComment.text.count == 0 {
return
}
ref.childByAutoId().setValue(["msg": txtComment.text,
"name": "Seller",
"status": "unread",
"timestamp": ServerValue.timestamp()
])
txtComment.text = ""
}
@IBAction func endService() {
let alerController = UIAlertController(title: "", message: "Is the service finished?", preferredStyle: .alert)
......@@ -54,18 +110,21 @@ extension OnlineEnquiryViewController {
extension OnlineEnquiryViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
return chats.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 || indexPath.row == 4 {
let customerCell = tableView.dequeueReusableCell(withIdentifier: "customer") as! OnlineEnquiryCustomerCell
customerCell.updateUI()
return customerCell
}else{
let chat = chats[indexPath.row]
if chat.name == "Seller" {
let masterCell = tableView.dequeueReusableCell(withIdentifier: "master") as! OnlineEnquiryMasterCell
masterCell.updateUI()
masterCell.lblMessage.text = chat.msg
return masterCell
} else {
let customerCell = tableView.dequeueReusableCell(withIdentifier: "customer") as! OnlineEnquiryCustomerCell
customerCell.lblMessage.text = chat.msg
return customerCell
}
......@@ -88,14 +147,27 @@ extension OnlineEnquiryViewController: UITextViewDelegate {
}
class OnlineEnquiryMasterCell: UITableViewCell {
@IBOutlet var imgMaster: UIImageView!
@IBOutlet var lblMessage: UILabel!
func updateUI() {
override func layoutIfNeeded() {
imgMaster.layer.cornerRadius = imgMaster.frame.size.width/2
}
}
class OnlineEnquiryCustomerCell: UITableViewCell {
......@@ -103,7 +175,8 @@ class OnlineEnquiryCustomerCell: UITableViewCell {
@IBOutlet var imgCostomer: UIImageView!
@IBOutlet var lblMessage: UILabel!
func updateUI() {
// imgCostomer.layer.cornerRadius = imgCostomer.frame.size.width/2
override func layoutIfNeeded() {
imgCostomer.layer.cornerRadius = imgCostomer.frame.size.width/2
}
}
......@@ -53,7 +53,6 @@ extension CorporateCultureViewController {
@IBAction func back() {
self.navigationController?.popViewController(animated: true)
}
}
......
//
// Chat.swift
// Bhagyashree
//
// Created by SunarcMAC on 07/08/18.
// Copyright © 2018 Sunarc. All rights reserved.
//
import Foundation
import FirebaseDatabase
class Chat {
let msg: String!
let name: String!
let readStatus: String!
var timeStamp: TimeInterval = 0
let chatId: String!
init(json: [String: Any], chatId: String) {
self.msg = json["msg"] as! String
self.name = json["name"] as! String
self.readStatus = json["status"] as! String
self.chatId = chatId
if let timeStamp = json["timestamp"] as? Int64 {
self.timeStamp = TimeInterval(exactly: timeStamp)!
}
}
}
......@@ -52,11 +52,14 @@ extension User {
User.customerId = response["customerId"] as! Int
}
if let isSeller = response["isSeller"] as? Bool {
User.isSeller = isSeller
}
User.bannerImage = response["bannerImage"] as? String
User.customerFullName = response["customerName"] as? String
User.profileImage = response["profileImage"] as? String
User.customerEmail = response["customerEmail"] as? String
User.isSeller = response["isSeller"] as! Bool
if User.isSeller == false {
failure("Username or password are incorrect")
......
......@@ -18,5 +18,9 @@ target 'Bhagyashree' do
pod 'Crashlytics'
pod 'ImageSlideshow'
pod 'ImageSlideshow/Kingfisher'
pod 'Firebase/Core'
pod 'Firebase/Storage'
pod 'Firebase/Auth'
pod 'Firebase/Database'
end
......@@ -4,12 +4,57 @@ PODS:
- Fabric (~> 1.7.5)
- EasyToast (2.0.0)
- Fabric (1.7.5)
- Firebase/Auth (5.0.0):
- Firebase/CoreOnly
- FirebaseAuth (= 5.0.0)
- Firebase/Core (5.0.0):
- Firebase/CoreOnly
- FirebaseAnalytics (= 5.0.0)
- Firebase/CoreOnly (5.0.0):
- FirebaseCore (= 5.0.0)
- Firebase/Database (5.0.0):
- Firebase/CoreOnly
- FirebaseDatabase (= 5.0.0)
- Firebase/Storage (5.0.0):
- Firebase/CoreOnly
- FirebaseStorage (= 3.0.0)
- FirebaseAnalytics (5.0.0):
- FirebaseCore (~> 5.0)
- FirebaseInstanceID (~> 3.0)
- "GoogleToolboxForMac/NSData+zlib (~> 2.1)"
- nanopb (~> 0.3)
- FirebaseAuth (5.0.0):
- FirebaseCore (~> 5.0)
- GTMSessionFetcher/Core (~> 1.1)
- FirebaseCore (5.0.0):
- "GoogleToolboxForMac/NSData+zlib (~> 2.1)"
- FirebaseDatabase (5.0.0):
- FirebaseCore (~> 5.0)
- leveldb-library (~> 1.18)
- FirebaseInstanceID (3.0.0):
- FirebaseCore (~> 5.0)
- FirebaseStorage (3.0.0):
- FirebaseCore (~> 5.0)
- GTMSessionFetcher/Core (~> 1.1)
- GoogleToolboxForMac/Defines (2.1.4)
- "GoogleToolboxForMac/NSData+zlib (2.1.4)":
- GoogleToolboxForMac/Defines (= 2.1.4)
- GTMSessionFetcher/Core (1.1.15)
- ImageSlideshow (1.5.3):
- ImageSlideshow/Core (= 1.5.3)
- ImageSlideshow/Core (1.5.3)
- ImageSlideshow/Kingfisher (1.5.3):
- ImageSlideshow/Core
- Kingfisher (> 3.0)
- IQKeyboardManagerSwift (5.0.8)
- Kingfisher (4.7.0)
- leveldb-library (1.20)
- MJRefresh (3.1.14.1)
- nanopb (0.3.8):
- nanopb/decode (= 0.3.8)
- nanopb/encode (= 0.3.8)
- nanopb/decode (0.3.8)
- nanopb/encode (0.3.8)
- Pastel (0.3.0)
- Realm (3.3.0):
- Realm/Headers (= 3.3.0)
......@@ -26,7 +71,12 @@ DEPENDENCIES:
- Crashlytics
- EasyToast (= 2.0)
- Fabric
- ImageSlideshow (~> 1.5)
- Firebase/Auth
- Firebase/Core
- Firebase/Database
- Firebase/Storage
- ImageSlideshow
- ImageSlideshow/Kingfisher
- IQKeyboardManagerSwift (= 5.0.8)
- Kingfisher (= 4.7.0)
- MJRefresh (= 3.1.14.1)
......@@ -43,10 +93,21 @@ SPEC REPOS:
- Crashlytics
- EasyToast
- Fabric
- Firebase
- FirebaseAnalytics
- FirebaseAuth
- FirebaseCore
- FirebaseDatabase
- FirebaseInstanceID
- FirebaseStorage
- GoogleToolboxForMac
- GTMSessionFetcher
- ImageSlideshow
- IQKeyboardManagerSwift
- Kingfisher
- leveldb-library
- MJRefresh
- nanopb
- Pastel
- Realm
- RealmSwift
......@@ -60,10 +121,21 @@ SPEC CHECKSUMS:
Crashlytics: aee1a064cbbf99b32efa3f056a5f458d846bc8ff
EasyToast: 243209f3536e47ae0d9e12fe5330367d6a0d7b82
Fabric: ae7146a5f505ea370a1e44820b4b1dc8890e2890
Firebase: 4bd804448ab2596794698773d41520a0af101e65
FirebaseAnalytics: 19812b49fa5f283dd6b23edf8a14b5d477029ab8
FirebaseAuth: acbeef02fe7c3a26624e309849f3fe30c84115af
FirebaseCore: e46e4babb9de298fb2f736958edcc6da1dc60d73
FirebaseDatabase: 697eb53e5b4fe7cd4fa8756c1f82a9fca011345f
FirebaseInstanceID: 83e0040351565df711a5db3d8ebe5ea21aca998a
FirebaseStorage: 7ca4bb7b58a25fa647b04f524033fc7cb7eb272b
GoogleToolboxForMac: 91c824d21e85b31c2aae9bb011c5027c9b4e738f
GTMSessionFetcher: 5fa5b80fd20e439ef5f545fb2cb3ca6c6714caa2
ImageSlideshow: 24a1184909f589379ba2527ebcc77996881bb1f2
IQKeyboardManagerSwift: 2e7dc7f98c111458c1ea2b373f893e8cf95e2b97
Kingfisher: da6b005aa96d37698e3e4f1ccfe96a5b9bbf27d6
leveldb-library: 08cba283675b7ed2d99629a4bc5fd052cd2bb6a5
MJRefresh: 238e6a37e2dba12160ee3b79f6d2a2b26abcab42
nanopb: 5601e6bca2dbf1ed831b519092ec110f66982ca3
Pastel: 738740c84f2b15bbcd96ebe99c4e6c2f5dd42262
Realm: 7d74ad6c5020432f58fe5e1df90bb6d97b2c7fef
RealmSwift: b2fa31a09c22e246026766557405505eeaad2b01
......@@ -72,6 +144,6 @@ SPEC CHECKSUMS:
TimeAgoInWords: 633dbb30810de855333dedd1d5033d28b1ecfd6f
WMPageController: 9f219bb8912a1a1f51af11fde61e2682a7b7e7f2
PODFILE CHECKSUM: 906849583379fc9a5f9af3fe162ae07b90c214ab
PODFILE CHECKSUM: 612cf2d8c67fd5ad7333652e83c98b9778d9881e
COCOAPODS: 1.5.3
#import <FirebaseCore/FirebaseCore.h>
#if !defined(__has_include)
#error "Firebase.h won't import anything if your compiler doesn't support __has_include. Please \
import the headers individually."
#else
#if __has_include(<FirebaseAnalytics/FirebaseAnalytics.h>)
#import <FirebaseAnalytics/FirebaseAnalytics.h>
#else
#ifndef FIREBASE_ANALYTICS_SUPPRESS_WARNING
#warning "FirebaseAnalytics.framework is not included in your target. Please add \
`Firebase/Core` to your Podfile or add FirebaseAnalytics.framework to your project to ensure \
Firebase services work as intended."
#endif // #ifndef FIREBASE_ANALYTICS_SUPPRESS_WARNING
#endif
#if __has_include(<FirebaseAuth/FirebaseAuth.h>)
#import <FirebaseAuth/FirebaseAuth.h>
#endif
#if __has_include(<FirebaseCrash/FirebaseCrash.h>)
#import <FirebaseCrash/FirebaseCrash.h>
#endif
#if __has_include(<FirebaseDatabase/FirebaseDatabase.h>)
#import <FirebaseDatabase/FirebaseDatabase.h>
#endif
#if __has_include(<FirebaseDynamicLinks/FirebaseDynamicLinks.h>)
#import <FirebaseDynamicLinks/FirebaseDynamicLinks.h>
#endif
#if __has_include(<FirebaseFirestore/FirebaseFirestore.h>)
#import <FirebaseFirestore/FirebaseFirestore.h>
#endif
#if __has_include(<FirebaseFunctions/FirebaseFunctions.h>)
#import <FirebaseFunctions/FirebaseFunctions.h>
#endif
#if __has_include(<FirebaseInstanceID/FirebaseInstanceID.h>)
#import <FirebaseInstanceID/FirebaseInstanceID.h>
#endif
#if __has_include(<FirebaseInvites/FirebaseInvites.h>)
#import <FirebaseInvites/FirebaseInvites.h>
#endif
#if __has_include(<FirebaseMessaging/FirebaseMessaging.h>)
#import <FirebaseMessaging/FirebaseMessaging.h>
#endif
#if __has_include(<FirebaseMLModelInterpreter/FirebaseMLModelInterpreter.h>)
#import <FirebaseMLModelInterpreter/FirebaseMLModelInterpreter.h>
#endif
#if __has_include(<FirebaseMLVision/FirebaseMLVision.h>)
#import <FirebaseMLVision/FirebaseMLVision.h>
#endif
#if __has_include(<FirebaseMLVisionBarcodeModel/FirebaseMLVisionBarcodeModel.h>)
#import <FirebaseMLVisionBarcodeModel/FirebaseMLVisionBarcodeModel.h>
#endif
#if __has_include(<FirebaseMLVisionFaceModel/FirebaseMLVisionFaceModel.h>)
#import <FirebaseMLVisionFaceModel/FirebaseMLVisionFaceModel.h>
#endif
#if __has_include(<FirebaseMLVisionLabelModel/FirebaseMLVisionLabelModel.h>)
#import <FirebaseMLVisionLabelModel/FirebaseMLVisionLabelModel.h>
#endif
#if __has_include(<FirebaseMLVisionTextModel/FirebaseMLVisionTextModel.h>)
#import <FirebaseMLVisionTextModel/FirebaseMLVisionTextModel.h>
#endif
#if __has_include(<FirebasePerformance/FirebasePerformance.h>)
#import <FirebasePerformance/FirebasePerformance.h>
#endif
#if __has_include(<FirebaseRemoteConfig/FirebaseRemoteConfig.h>)
#import <FirebaseRemoteConfig/FirebaseRemoteConfig.h>
#endif
#if __has_include(<FirebaseStorage/FirebaseStorage.h>)
#import <FirebaseStorage/FirebaseStorage.h>
#endif
#if __has_include(<GoogleMobileAds/GoogleMobileAds.h>)
#import <GoogleMobileAds/GoogleMobileAds.h>
#endif
#if __has_include(<Fabric/Fabric.h>)
#import <Fabric/Fabric.h>
#endif
#if __has_include(<Crashlytics/Crashlytics.h>)
#import <Crashlytics/Crashlytics.h>
#endif
#endif // defined(__has_include)
module Firebase {
export *
header "Firebase.h"
}
\ No newline at end of file
# Firebase APIs for iOS
Simplify your iOS development, grow your user base, and monetize more
effectively with Firebase services.
Much more information can be found at [https://firebase.google.com](https://firebase.google.com).
## Install a Firebase SDK using CocoaPods
Firebase distributes several iOS specific APIs and SDKs via CocoaPods.
You can install the CocoaPods tool on OS X by running the following command from
the terminal. Detailed information is available in the [Getting Started
guide](https://guides.cocoapods.org/using/getting-started.html#getting-started).
```
$ sudo gem install cocoapods
```
## Try out an SDK
You can try any of the SDKs with `pod try`. Run the following command and select
the SDK you are interested in when prompted:
```
$ pod try Firebase
```
Note that some SDKs may require credentials. More information is available in
the SDK-specific documentation at [https://firebase.google.com/docs/](https://firebase.google.com/docs/).
## Add a Firebase SDK to your iOS app
CocoaPods is used to install and manage dependencies in existing Xcode projects.
1. Create an Xcode project, and save it to your local machine.
2. Create a file named `Podfile` in your project directory. This file defines
your project's dependencies, and is commonly referred to as a Podspec.
3. Open `Podfile`, and add your dependencies. A simple Podspec is shown here:
```
platform :ios, '8.0'
pod 'Firebase'
```
4. Save the file.
5. Open a terminal and `cd` to the directory containing the Podfile.
```
$ cd <path-to-project>/project/
```
6. Run the `pod install` command. This will install the SDKs specified in the
Podspec, along with any dependencies they may have.
```
$ pod install
```
7. Open your app's `.xcworkspace` file to launch Xcode. Use this file for all
development on your app.
8. You can also install other Firebase SDKs by adding the subspecs in the
Podfile.
```
pod 'Firebase/AdMob'
pod 'Firebase/Analytics'
pod 'Firebase/Auth'
pod 'Firebase/Crash'
pod 'Firebase/Database'
pod 'Firebase/DynamicLinks'
pod 'Firebase/Firestore'
pod 'Firebase/Functions'
pod 'Firebase/Invites'
pod 'Firebase/Messaging'
pod 'Firebase/MLCommon'
pod 'Firebase/MLModelInterpreter'
pod 'Firebase/MLVision'
pod 'Firebase/MLVisionBarcodeModel'
pod 'Firebase/MLVisionFaceModel'
pod 'Firebase/MLVisionLabelModel'
pod 'Firebase/MLVisionTextModel'
pod 'Firebase/Performance'
pod 'Firebase/RemoteConfig'
pod 'Firebase/Storage'
```
#import <Foundation/Foundation.h>
#import "FIRAnalytics.h"
NS_ASSUME_NONNULL_BEGIN
/**
* Provides App Delegate handlers to be used in your App Delegate.
*
* To save time integrating Firebase Analytics in an application, Firebase Analytics does not
* require delegation implementation from the AppDelegate. Instead this is automatically done by
* Firebase Analytics. Should you choose instead to delegate manually, you can turn off the App
* Delegate Proxy by adding FirebaseAppDelegateProxyEnabled into your app's Info.plist and setting
* it to NO, and adding the methods in this category to corresponding delegation handlers.
*
* To handle Universal Links, you must return YES in
* [UIApplicationDelegate application:didFinishLaunchingWithOptions:].
*/
@interface FIRAnalytics (AppDelegate)
/**
* Handles events related to a URL session that are waiting to be processed.
*
* For optimal use of Firebase Analytics, call this method from the
* [UIApplicationDelegate application:handleEventsForBackgroundURLSession:completionHandler]
* method of the app delegate in your app.
*
* @param identifier The identifier of the URL session requiring attention.
* @param completionHandler The completion handler to call when you finish processing the events.
* Calling this completion handler lets the system know that your app's user interface is
* updated and a new snapshot can be taken.
*/
+ (void)handleEventsForBackgroundURLSession:(NSString *)identifier
completionHandler:(nullable void (^)(void))completionHandler;
/**
* Handles the event when the app is launched by a URL.
*
* Call this method from [UIApplicationDelegate application:openURL:options:] &#40;on iOS 9.0 and
* above&#41;, or [UIApplicationDelegate application:openURL:sourceApplication:annotation:] &#40;on
* iOS 8.x and below&#41; in your app.
*
* @param url The URL resource to open. This resource can be a network resource or a file.
*/
+ (void)handleOpenURL:(NSURL *)url;
/**
* Handles the event when the app receives data associated with user activity that includes a
* Universal Link (on iOS 9.0 and above).
*
* Call this method from [UIApplication continueUserActivity:restorationHandler:] in your app
* delegate (on iOS 9.0 and above).
*
* @param userActivity The activity object containing the data associated with the task the user
* was performing.
*/
+ (void)handleUserActivity:(id)userActivity;
@end
NS_ASSUME_NONNULL_END
#import <Foundation/Foundation.h>
#import "FIREventNames.h"
#import "FIRParameterNames.h"
#import "FIRUserPropertyNames.h"
NS_ASSUME_NONNULL_BEGIN
/// The top level Firebase Analytics singleton that provides methods for logging events and setting
/// user properties. See <a href="http://goo.gl/gz8SLz">the developer guides</a> for general
/// information on using Firebase Analytics in your apps.
NS_SWIFT_NAME(Analytics)
@interface FIRAnalytics : NSObject
/// Logs an app event. The event can have up to 25 parameters. Events with the same name must have
/// the same parameters. Up to 500 event names are supported. Using predefined events and/or
/// parameters is recommended for optimal reporting.
///
/// The following event names are reserved and cannot be used:
/// <ul>
/// <li>ad_activeview</li>
/// <li>ad_click</li>
/// <li>ad_exposure</li>
/// <li>ad_impression</li>
/// <li>ad_query</li>
/// <li>adunit_exposure</li>
/// <li>app_clear_data</li>
/// <li>app_remove</li>
/// <li>app_update</li>
/// <li>error</li>
/// <li>first_open</li>
/// <li>in_app_purchase</li>
/// <li>notification_dismiss</li>
/// <li>notification_foreground</li>
/// <li>notification_open</li>
/// <li>notification_receive</li>
/// <li>os_update</li>
/// <li>screen_view</li>
/// <li>session_start</li>
/// <li>user_engagement</li>
/// </ul>
///
/// @param name The name of the event. Should contain 1 to 40 alphanumeric characters or
/// underscores. The name must start with an alphabetic character. Some event names are
/// reserved. See FIREventNames.h for the list of reserved event names. The "firebase_",
/// "google_", and "ga_" prefixes are reserved and should not be used. Note that event names are
/// case-sensitive and that logging two events whose names differ only in case will result in
/// two distinct events.
/// @param parameters The dictionary of event parameters. Passing nil indicates that the event has
/// no parameters. Parameter names can be up to 40 characters long and must start with an
/// alphabetic character and contain only alphanumeric characters and underscores. Only NSString
/// and NSNumber (signed 64-bit integer and 64-bit floating-point number) parameter types are
/// supported. NSString parameter values can be up to 100 characters long. The "firebase_",
/// "google_", and "ga_" prefixes are reserved and should not be used for parameter names.
+ (void)logEventWithName:(NSString *)name
parameters:(nullable NSDictionary<NSString *, id> *)parameters
NS_SWIFT_NAME(logEvent(_:parameters:));
/// Sets a user property to a given value. Up to 25 user property names are supported. Once set,
/// user property values persist throughout the app lifecycle and across sessions.
///
/// The following user property names are reserved and cannot be used:
/// <ul>
/// <li>first_open_time</li>
/// <li>last_deep_link_referrer</li>
/// <li>user_id</li>
/// </ul>
///
/// @param value The value of the user property. Values can be up to 36 characters long. Setting the
/// value to nil removes the user property.
/// @param name The name of the user property to set. Should contain 1 to 24 alphanumeric characters
/// or underscores and must start with an alphabetic character. The "firebase_", "google_", and
/// "ga_" prefixes are reserved and should not be used for user property names.
+ (void)setUserPropertyString:(nullable NSString *)value forName:(NSString *)name
NS_SWIFT_NAME(setUserProperty(_:forName:));
/// Sets the user ID property. This feature must be used in accordance with
/// <a href="https://www.google.com/policies/privacy">Google's Privacy Policy</a>
///
/// @param userID The user ID to ascribe to the user of this app on this device, which must be
/// non-empty and no more than 256 characters long. Setting userID to nil removes the user ID.
+ (void)setUserID:(nullable NSString *)userID;
/// Sets the current screen name, which specifies the current visual context in your app. This helps
/// identify the areas in your app where users spend their time and how they interact with your app.
/// Must be called on the main thread.
///
/// Note that screen reporting is enabled automatically and records the class name of the current
/// UIViewController for you without requiring you to call this method. If you implement
/// viewDidAppear in your UIViewController but do not call [super viewDidAppear:], that screen class
/// will not be automatically tracked. The class name can optionally be overridden by calling this
/// method in the viewDidAppear callback of your UIViewController and specifying the
/// screenClassOverride parameter. setScreenName:screenClass: must be called after
/// [super viewDidAppear:].
///
/// If your app does not use a distinct UIViewController for each screen, you should call this
/// method and specify a distinct screenName each time a new screen is presented to the user.
///
/// The screen name and screen class remain in effect until the current UIViewController changes or
/// a new call to setScreenName:screenClass: is made.
///
/// @param screenName The name of the current screen. Should contain 1 to 100 characters. Set to nil
/// to clear the current screen name.
/// @param screenClassOverride The name of the screen class. Should contain 1 to 100 characters. By
/// default this is the class name of the current UIViewController. Set to nil to revert to the
/// default class name.
+ (void)setScreenName:(nullable NSString *)screenName
screenClass:(nullable NSString *)screenClassOverride;
/// The unique ID for this instance of the application.
+ (NSString *)appInstanceID;
/// Clears all analytics data for this instance from the device and resets the app instance ID.
/// FIRAnalyticsConfiguration values will be reset to the default values.
+ (void)resetAnalyticsData;
@end
NS_ASSUME_NONNULL_END
#ifndef FIR_SWIFT_NAME
#import <Foundation/Foundation.h>
// NS_SWIFT_NAME can only translate factory methods before the iOS 9.3 SDK.
// Wrap it in our own macro if it's a non-compatible SDK.
#ifdef __IPHONE_9_3
#define FIR_SWIFT_NAME(X) NS_SWIFT_NAME(X)
#else
#define FIR_SWIFT_NAME(X) // Intentionally blank.
#endif // #ifdef __IPHONE_9_3
#endif // FIR_SWIFT_NAME
/// @file FIRUserPropertyNames.h
///
/// Predefined user property names.
///
/// A UserProperty is an attribute that describes the app-user. By supplying UserProperties, you can
/// later analyze different behaviors of various segments of your userbase. You may supply up to 25
/// unique UserProperties per app, and you can use the name and value of your choosing for each one.
/// UserProperty names can be up to 24 characters long, may only contain alphanumeric characters and
/// underscores ("_"), and must start with an alphabetic character. UserProperty values can be up to
/// 36 characters long. The "firebase_", "google_", and "ga_" prefixes are reserved and should not
/// be used.
#import <Foundation/Foundation.h>
/// The method used to sign in. For example, "google", "facebook" or "twitter".
static NSString *const kFIRUserPropertySignUpMethod
NS_SWIFT_NAME(AnalyticsUserPropertySignUpMethod) = @"sign_up_method";
#import "FIRAnalytics+AppDelegate.h"
#import "FIRAnalytics.h"
#import "FIRAnalyticsSwiftNameSupport.h"
#import "FIREventNames.h"
#import "FIRParameterNames.h"
#import "FIRUserPropertyNames.h"
framework module FirebaseAnalytics {
umbrella header "FirebaseAnalytics.h"
export *
module * { export *}
link "sqlite3"
link "z"
link framework "Security"
link framework "StoreKit"
link framework "SystemConfiguration"
link framework "UIKit"}
framework module FirebaseCoreDiagnostics {
export *
module * { export *}
link "z"
link framework "Security"
link framework "SystemConfiguration"}
# v4.6.1
- Fixes crash which occurred when certain Firebase IDTokens were being parsed (#1076).
# v4.6.0
- Adds `getIDTokenResultWithCompletion:` and `getIDTokenResultForcingRefresh:completion:` APIs which
call back with an AuthTokenResult object. The Auth token result object contains the ID token JWT string and other properties associated with the token including the decoded available payload claims (#1004).
- Adds the `updateCurrentUser:completion:` API which sets the currentUser on the calling Auth instance to the provided user object (#1018).
- Adds client-side validation to prevent setting `handleCodeInApp` to false when performing
email-link authentication. If `handleCodeInApp` is set to false an invalid argument exception
is thrown (#931).
- Adds support for passing the deep link (which is embedded in the sign-in link sent via email) to the
`signInWithEmail:link:completion:` and `isSignInWithEmailLink:` methods during an
email/link sign-in flow (#1023).
# v4.5.0
- Adds new API which provides a way to determine the sign-in methods associated with an
email address.
- Adds new API which allows authentication using only an email link (Passwordless Authentication
with email link).
# v4.4.4
- Addresses CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF warnings that surface in newer versions of
Xcode and CocoaPods.
- Improves FIRUser documentation with clear message explaining when Firebase Auth attempts to validate
users and what happens when an invalidated user is detected (#694) .
# v4.4.3
- Adds an explicit dependency on CoreGraphics from Firebase Auth.
# v4.4.2
- Fixes bug where the FIRAuthResult object returned following a Phone Number authentication
always contained a nil FIRAdditionalUserInfo object. Now the FIRAdditionalUserInfo object is
never nil and its newUser field is populated correctly.
# v4.4.0
- Adds new APIs which return an AuthDataResult object after successfully creating an
Email/Password user, signing in anonymously, signing in with Email/Password and signing
in with Custom Token. The AuthDataResult object contains the new user and additional
information pertaining to the new user.
# v4.3.2
- Improves error handling for the phone number sign-in reCAPTCHA flow.
- Improves error handling for phone number linking flow.
- Fixes issue where after linking an anonymous user to a phone number the user remained
anonymous.
# v4.3.1
- Internal clean up.
# v4.3.0
- Provides account creation and last sign-in dates as metadata to the user
object.
- Returns more descriptive errors for some error cases of the phone number
sign-in reCAPTCHA flow.
- Fixes an issue that invalid users were not automatically signed out earlier.
- Fixes an issue that ID token listeners were not fired in some cases.
# v4.2.1
- Fixes a threading issue in phone number auth that completion block was not
executed on the main thread in some error cases.
# v4.2.0
- Adds new phone number verification API which makes use of an intelligent reCAPTCHA to verify the application.
# v4.1.1
- Improves some method documentation in headers.
# v4.1.0
- Allows the app to handle continue URL natively, e.g., from password reset
email.
- Allows the app to set language code, e.g., for sending password reset email.
- Fixes an issue that user's phone number did not persist on client.
- Fixes an issue that recover email action code type was reported as unknown.
- Improves app start-up time by moving initialization off from the main
thread.
- Better reports missing email error when creating a new password user.
- Changes console message logging levels to be more consistent with other
Firebase products on the iOS platform.
# 2017-05-17 -- v4.0.0
- Adds Phone Number Authentication.
- Adds support for generic OAuth2 identity providers.
- Adds methods that return additional user data from identity providers if
available when authenticating users.
- Improves session management by automatically refreshing tokens if possible
and signing out users if the session is detected invalidated, for example,
after the user changed password or deleted account from another device.
- Fixes an issue that reauthentication creates new user account if the user
credential is valid but does not match the currently signed in user.
- Fixes an issue that the "password" provider is not immediately listed on the
client side after adding a password to an account.
- Changes factory methods to return non-null FIRAuth instances or raises an
exception, instead of returning nullable instances.
- Changes auth state change listener to only be triggered when the user changes.
- Adds a new listener which is triggered whenever the ID token is changed.
- Switches ERROR_EMAIL_ALREADY_IN_USE to
ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL when the email used in the
signInWithCredential: call is already in use by another account.
- Deprecates FIREmailPasswordAuthProvider in favor of FIREmailAuthProvider.
- Deprecates getTokenWithCompletion in favor of getIDTokenWithCompletion on
FIRUser.
- Changes Swift API names to better align with Swift convention.
# 2017-02-06 -- v3.1.1
- Allows handling of additional errors when sending OOB action emails. The
server can respond with the following new error messages:
INVALID_MESSAGE_PAYLOAD,INVALID_SENDER and INVALID_RECIPIENT_EMAIL.
- Removes incorrect reference to FIRAuthErrorCodeCredentialTooOld in FIRUser.h.
- Provides additional error information from server if available.
# 2016-12-13 -- v3.1.0
- Adds FIRAuth methods that enable the app to follow up with user actions
delivered by email, such as verifying email address or reset password.
- No longer applies the keychain workaround introduced in v3.0.5 on iOS 10.2
simulator or above since the issue has been fixed.
- Fixes nullability compilation warnings when used in Swift.
- Better reports missing password error.
# 2016-10-24 -- v3.0.6
- Switches to depend on open sourced GoogleToolboxForMac and GTMSessionFetcher.
- Improves logging of keychain error when initializing.
# 2016-09-14 -- v3.0.5
- Works around a keychain issue in iOS 10 simulator.
- Reports the correct error for invalid email when signing in with email and
password.
# 2016-07-18 -- v3.0.4
- Fixes a race condition bug that could crash the app with an exception from
NSURLSession on iOS 9.
# 2016-06-20 -- v3.0.3
- Adds documentation for all possible errors returned by each method.
- Improves error handling and messages for a variety of error conditions.
- Whether or not an user is considered anonymous is now consistent with other
platforms.
- A saved signed in user is now siloed between different Firebase projects
within the same app.
# 2016-05-18 -- v3.0.2
- Initial public release.
# Firebase Auth for iOS
Firebase Auth enables apps to easily support multiple authentication options
for their end users.
Please visit [our developer site](https://firebase.google.com/docs/auth/) for
integration instructions, documentation, support information, and terms of
service.
# Firebase Auth Development
Example/Auth contains a set of samples and tests that integrate with
FirebaseAuth.
The unit tests run without any additional configuration along with the rest of
Firebase. See [Example/Auth/README.md](../../Example/Auth/README.md) for
information about setting up, running, and testing the samples.
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIREmailAuthProvider.h"
#import "FIREmailPasswordAuthCredential.h"
// FIREmailPasswordAuthProviderID is defined in FIRAuthProvider.m.
@implementation FIREmailAuthProvider
- (instancetype)init {
@throw [NSException exceptionWithName:@"Attempt to call unavailable initializer."
reason:@"This class is not meant to be initialized."
userInfo:nil];
}
+ (FIRAuthCredential *)credentialWithEmail:(NSString *)email password:(NSString *)password {
return [[FIREmailPasswordAuthCredential alloc] initWithEmail:email password:password];
}
+ (FIRAuthCredential *)credentialWithEmail:(NSString *)email link:(NSString *)link {
return [[FIREmailPasswordAuthCredential alloc] initWithEmail:email link:link];
}
@end
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthCredential_Internal.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIREmailPasswordAuthCredential
@brief Internal implementation of FIRAuthCredential for Email/Password credentials.
*/
@interface FIREmailPasswordAuthCredential : FIRAuthCredential
/** @property email
@brief The user's email address.
*/
@property(nonatomic, readonly) NSString *email;
/** @property password
@brief The user's password.
*/
@property(nonatomic, readonly) NSString *password;
/** @property link
@brief The email sign-in link.
*/
@property(nonatomic, readonly) NSString *link;
/** @fn initWithEmail:password:
@brief Designated initializer.
@param email The user's email address.
@param password The user's password.
*/
- (nullable instancetype)initWithEmail:(NSString *)email password:(NSString *)password
NS_DESIGNATED_INITIALIZER;
/** @fn initWithEmail:link:
@brief Designated initializer.
@param email The user's email address.
@param link The email sign-in link.
*/
- (nullable instancetype)initWithEmail:(NSString *)email link:(NSString *)link
NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIREmailPasswordAuthCredential.h"
#import "FIREmailAuthProvider.h"
#import "FIRAuthExceptionUtils.h"
#import "FIRVerifyAssertionRequest.h"
@interface FIREmailPasswordAuthCredential ()
- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE;
@end
@implementation FIREmailPasswordAuthCredential
- (nullable instancetype)initWithProvider:(NSString *)provider {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"Please call the designated initializer."];
return nil;
}
- (nullable instancetype)initWithEmail:(NSString *)email password:(NSString *)password {
self = [super initWithProvider:FIREmailAuthProviderID];
if (self) {
_email = [email copy];
_password = [password copy];
}
return self;
}
- (nullable instancetype)initWithEmail:(NSString *)email link:(NSString *)link {
self = [super initWithProvider:FIREmailAuthProviderID];
if (self) {
_email = [email copy];
_link = [link copy];
}
return self;
}
- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"Attempt to call prepareVerifyAssertionRequest: on a FIREmailPasswordAuthCredential."];
}
@end
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthCredential_Internal.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIRFacebookAuthCredential
@brief Internal implementation of FIRAuthCredential for the Facebook IdP.
*/
@interface FIRFacebookAuthCredential : FIRAuthCredential
/** @fn initWithAccessToken:
@brief Designated initializer.
@param accessToken The Access Token obtained from Facebook.
*/
- (nullable instancetype)initWithAccessToken:(NSString *)accessToken NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRFacebookAuthCredential.h"
#import "FIRFacebookAuthProvider.h"
#import "FIRAuthExceptionUtils.h"
#import "FIRVerifyAssertionRequest.h"
@interface FIRFacebookAuthCredential ()
- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE;
@end
@implementation FIRFacebookAuthCredential {
NSString *_accessToken;
}
- (nullable instancetype)initWithProvider:(NSString *)provider {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"Please call the designated initializer."];
return nil;
}
- (nullable instancetype)initWithAccessToken:(NSString *)accessToken {
self = [super initWithProvider:FIRFacebookAuthProviderID];
if (self) {
_accessToken = [accessToken copy];
}
return self;
}
- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request {
request.providerAccessToken = _accessToken;
}
@end
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRFacebookAuthProvider.h"
#import "FIRFacebookAuthCredential.h"
#import "FIRAuthExceptionUtils.h"
// FIRFacebookAuthProviderID is defined in FIRAuthProvider.m.
@implementation FIRFacebookAuthProvider
- (instancetype)init {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"This class is not meant to be initialized."];
return nil;
}
+ (FIRAuthCredential *)credentialWithAccessToken:(NSString *)accessToken {
return [[FIRFacebookAuthCredential alloc] initWithAccessToken:accessToken];
}
@end
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthCredential_Internal.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIRGitHubAuthCredential
@brief Internal implementation of FIRAuthCredential for GitHub credentials.
*/
@interface FIRGitHubAuthCredential : FIRAuthCredential
/** @property token
@brief The GitHub OAuth access token.
*/
@property(nonatomic, readonly) NSString *token;
/** @fn initWithToken:
@brief Designated initializer.
@param token The GitHub OAuth access token.
*/
- (nullable instancetype)initWithToken:(NSString *)token NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRGitHubAuthCredential.h"
#import "FIRGitHubAuthProvider.h"
#import "FIRAuthExceptionUtils.h"
#import "FIRVerifyAssertionRequest.h"
@interface FIRGitHubAuthCredential ()
- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE;
@end
@implementation FIRGitHubAuthCredential
- (nullable instancetype)initWithProvider:(NSString *)provider {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"Please call the designated initializer."];
return nil;
}
- (nullable instancetype)initWithToken:(NSString *)token {
self = [super initWithProvider:FIRGitHubAuthProviderID];
if (self) {
_token = [token copy];
}
return self;
}
- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request {
request.providerAccessToken = _token;
}
@end
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRGitHubAuthProvider.h"
#import "FIRGitHubAuthCredential.h"
#import "FIRAuthExceptionUtils.h"
// FIRGitHubAuthProviderID is defined in FIRAuthProvider.m.
@implementation FIRGitHubAuthProvider
- (instancetype)init {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"This class is not meant to be initialized."];
return nil;
}
+ (FIRAuthCredential *)credentialWithToken:(NSString *)token {
return [[FIRGitHubAuthCredential alloc] initWithToken:token];
}
@end
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthCredential_Internal.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIRGoogleAuthCredential
@brief Internal implementation of FIRAuthCredential for the Google IdP.
*/
@interface FIRGoogleAuthCredential : FIRAuthCredential
/** @fn initWithIDToken:accessToken:
@brief Designated initializer.
@param IDToken The ID Token obtained from Google.
@param accessToken The Access Token obtained from Google.
*/
- (nullable instancetype)initWithIDToken:(NSString *)IDToken accessToken:(NSString *)accessToken
NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRGoogleAuthCredential.h"
#import "FIRGoogleAuthProvider.h"
#import "FIRAuthExceptionUtils.h"
#import "FIRVerifyAssertionRequest.h"
@interface FIRGoogleAuthCredential ()
- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE;
@end
@implementation FIRGoogleAuthCredential {
NSString *_IDToken;
NSString *_accessToken;
}
- (nullable instancetype)initWithProvider:(NSString *)provider {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"Please call the designated initializer."];
return nil;
}
- (nullable instancetype)initWithIDToken:(NSString *)IDToken accessToken:(NSString *)accessToken {
self = [super initWithProvider:FIRGoogleAuthProviderID];
if (self) {
_IDToken = [IDToken copy];
_accessToken = [accessToken copy];
}
return self;
}
- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request {
request.providerIDToken = _IDToken;
request.providerAccessToken = _accessToken;
}
@end
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRGoogleAuthProvider.h"
#import "FIRGoogleAuthCredential.h"
#import "FIRAuthExceptionUtils.h"
// FIRGoogleAuthProviderID is defined in FIRAuthProvider.m.
@implementation FIRGoogleAuthProvider
- (instancetype)init {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"This class is not meant to be initialized."];
return nil;
}
+ (FIRAuthCredential *)credentialWithIDToken:(NSString *)IDToken
accessToken:(NSString *)accessToken {
return [[FIRGoogleAuthCredential alloc] initWithIDToken:IDToken accessToken:accessToken];
}
@end
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthCredential_Internal.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIROAuthCredential
@brief Internal implementation of FIRAuthCredential for generic credentials.
*/
@interface FIROAuthCredential : FIRAuthCredential
/** @property IDToken
@brief The ID Token associated with this credential.
*/
@property(nonatomic, readonly, nullable) NSString *IDToken;
/** @property accessToken
@brief The access token associated with this credential.
*/
@property(nonatomic, readonly, nullable) NSString *accessToken;
/** @fn initWithProviderId:IDToken:accessToken:
@brief Designated initializer.
@param providerID The provider ID associated with the credential being created.
@param IDToken The ID Token associated with the credential being created.
@param accessToken The access token associated with the credential being created.
*/
- (nullable instancetype)initWithProviderID:(NSString *)providerID
IDToken:(nullable NSString*)IDToken
accessToken:(nullable NSString *)accessToken;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIROAuthCredential.h"
#import "FIRVerifyAssertionRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface FIROAuthCredential ()
- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE;
@end
@implementation FIROAuthCredential
- (nullable instancetype)initWithProviderID:(NSString *)providerID
IDToken:(nullable NSString *)IDToken
accessToken:(nullable NSString *)accessToken {
self = [super initWithProvider:providerID];
if (self) {
_IDToken = IDToken;
_accessToken = accessToken;
}
return self;
}
- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request {
request.providerIDToken = _IDToken;
request.providerAccessToken = _accessToken;
}
NS_ASSUME_NONNULL_END
@end
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIROAuthProvider.h"
#import "FIROAuthCredential.h"
NS_ASSUME_NONNULL_BEGIN
@implementation FIROAuthProvider
+ (FIRAuthCredential *)credentialWithProviderID:(NSString *)providerID
IDToken:(NSString *)IDToken
accessToken:(nullable NSString *)accessToken {
return [[FIROAuthCredential alloc] initWithProviderID:providerID
IDToken:IDToken
accessToken:accessToken];
}
+ (FIROAuthCredential *)credentialWithProviderID:(NSString *)providerID
accessToken:(NSString *)accessToken {
return [[FIROAuthCredential alloc] initWithProviderID:providerID
IDToken:nil
accessToken:accessToken];
}
NS_ASSUME_NONNULL_END
@end
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRPhoneAuthCredential.h"
#import "FIRPhoneAuthCredential_Internal.h"
#import "FIRAuthCredential_Internal.h"
#import "FIRAuthExceptionUtils.h"
#import "FIRVerifyAssertionRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface FIRPhoneAuthCredential ()
- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE;
@end
@implementation FIRPhoneAuthCredential
- (instancetype)initWithTemporaryProof:(NSString *)temporaryProof
phoneNumber:(NSString *)phoneNumber
providerID:(NSString *)providerID {
self = [super initWithProvider:providerID];
if (self) {
_temporaryProof = [temporaryProof copy];
_phoneNumber = [phoneNumber copy];
}
return self;
}
- (nullable instancetype)initWithProvider:(NSString *)provider {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"Please call the designated initializer."];
return nil;
}
- (instancetype)initWithProviderID:(NSString *)providerID
verificationID:(NSString *)verificationID
verificationCode:(NSString *)verificationCode {
self = [super initWithProvider:providerID];
if (self) {
_verificationID = [verificationID copy];
_verificationCode = [verificationCode copy];
}
return self;
}
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRPhoneAuthCredential.h"
NS_ASSUME_NONNULL_BEGIN
/** @extension FIRPhoneAuthCredential
@brief Internal implementation of FIRAuthCredential for Phone Auth credentials.
*/
@interface FIRPhoneAuthCredential ()
/** @var verificationID
@brief The verification ID obtained from invoking @c verifyPhoneNumber:completion:
*/
@property(nonatomic, readonly, nonnull) NSString *verificationID;
/** @var verificationCode
@brief The verification code provided by the user.
*/
@property(nonatomic, readonly, nonnull) NSString *verificationCode;
/** @var temporaryProof
@brief The a temporary proof code perftaining to this credential, returned from the backend.
*/
@property(nonatomic, readonly, nonnull) NSString *temporaryProof;
/** @var phoneNumber
@brief The a phone number pertaining to this credential, returned from the backend.
*/
@property(nonatomic, readonly, nonnull) NSString *phoneNumber;
/** @var initWithTemporaryProof:phoneNumber:
@brief Designated Initializer.
@param providerID The provider ID associated with the phone auth credential being created.
*/
- (instancetype)initWithTemporaryProof:(NSString *)temporaryProof
phoneNumber:(NSString *)phoneNumber
providerID:(NSString *)providerID NS_DESIGNATED_INITIALIZER;
/** @var initWithProviderID:verificationID:verificationCode:
@brief Designated Initializer.
@param providerID The provider ID associated with the phone auth credential being created.
@param verificationID The verification ID associated witht Phone Auth credential being created.
@param verificationCode The verification code associated witht Phone Auth credential being
created.
*/
- (instancetype)initWithProviderID:(NSString *)providerID
verificationID:(NSString *)verificationID
verificationCode:(NSString *)verificationCode NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthCredential_Internal.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIRTwitterAuthCredential
@brief Internal implementation of FIRAuthCredential for Twitter credentials.
*/
@interface FIRTwitterAuthCredential : FIRAuthCredential
/** @property token
@brief The Twitter OAuth token.
*/
@property(nonatomic, readonly) NSString *token;
/** @property secret
@brief The Twitter OAuth secret.
*/
@property(nonatomic, readonly) NSString *secret;
/** @fn initWithToken:secret:
@brief Designated initializer.
@param token The Twitter OAuth token.
@param secret The Twitter OAuth secret.
*/
- (nullable instancetype)initWithToken:(NSString *)token secret:(NSString *)secret
NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRTwitterAuthCredential.h"
#import "FIRTwitterAuthProvider.h"
#import "FIRAuthExceptionUtils.h"
#import "FIRVerifyAssertionRequest.h"
@interface FIRTwitterAuthCredential ()
- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE;
@end
@implementation FIRTwitterAuthCredential
- (nullable instancetype)initWithProvider:(NSString *)provider {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"Please call the designated initializer."];
return nil;
}
- (nullable instancetype)initWithToken:(NSString *)token secret:(NSString *)secret {
self = [super initWithProvider:FIRTwitterAuthProviderID];
if (self) {
_token = [token copy];
_secret = [secret copy];
}
return self;
}
- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request {
request.providerAccessToken = _token;
request.providerOAuthTokenSecret = _secret;
}
@end
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRTwitterAuthProvider.h"
#import "FIRTwitterAuthCredential.h"
#import "FIRAuthExceptionUtils.h"
// FIRTwitterAuthProviderID is defined in FIRAuthProvider.m.
@implementation FIRTwitterAuthProvider
- (instancetype)init {
[FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason:
@"This class is not meant to be initialized."];
return nil;
}
+ (FIRAuthCredential *)credentialWithToken:(NSString *)token secret:(NSString *)secret {
return [[FIRTwitterAuthCredential alloc] initWithToken:token secret:secret];
}
@end
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRActionCodeSettings.h"
NS_ASSUME_NONNULL_BEGIN
@implementation FIRActionCodeSettings
- (instancetype)init {
self = [super init];
if (self) {
_iOSBundleID = [NSBundle mainBundle].bundleIdentifier;
}
return self;
}
- (void)setIOSBundleID:(NSString *)iOSBundleID {
_iOSBundleID = [iOSBundleID copy];
}
- (void)setAndroidPackageName:(NSString *)androidPackageName
installIfNotAvailable:(BOOL)installIfNotAvailable
minimumVersion:(nullable NSString *)minimumVersion {
_androidPackageName = [androidPackageName copy];
_androidInstallIfNotAvailable = installIfNotAvailable;
_androidMinimumVersion = [minimumVersion copy];
}
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAdditionalUserInfo_Internal.h"
#import "FIRVerifyAssertionResponse.h"
NS_ASSUME_NONNULL_BEGIN
@implementation FIRAdditionalUserInfo
/** @var kProviderIDCodingKey
@brief The key used to encode the providerID property for NSSecureCoding.
*/
static NSString *const kProviderIDCodingKey = @"providerID";
/** @var kProfileCodingKey
@brief The key used to encode the profile property for NSSecureCoding.
*/
static NSString *const kProfileCodingKey = @"profile";
/** @var kUsernameCodingKey
@brief The key used to encode the username property for NSSecureCoding.
*/
static NSString *const kUsernameCodingKey = @"username";
/** @var kNewUserKey
@brief The key used to encode the newUser property for NSSecureCoding.
*/
static NSString *const kNewUserKey = @"newUser";
+ (nullable instancetype)userInfoWithVerifyAssertionResponse:
(FIRVerifyAssertionResponse *)verifyAssertionResponse {
return [[self alloc] initWithProviderID:verifyAssertionResponse.providerID
profile:verifyAssertionResponse.profile
username:verifyAssertionResponse.username
isNewUser:verifyAssertionResponse.isNewUser];
}
- (nullable instancetype)initWithProviderID:(nullable NSString *)providerID
profile:(nullable NSDictionary<NSString *, NSObject *> *)profile
username:(nullable NSString *)username
isNewUser:(BOOL)isNewUser {
self = [super init];
if (self) {
_providerID = [providerID copy];
if (profile) {
_profile = [[NSDictionary alloc] initWithDictionary:profile copyItems:YES];
}
_username = [username copy];
_newUser = isNewUser;
}
return self;
}
#pragma mark - NSSecureCoding
+ (BOOL)supportsSecureCoding {
return YES;
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
NSString *providerID =
[aDecoder decodeObjectOfClass:[NSString class] forKey:kProviderIDCodingKey];
NSDictionary<NSString *, NSObject *> *profile =
[aDecoder decodeObjectOfClass:[NSDictionary class] forKey:kProfileCodingKey];
NSString *username = [aDecoder decodeObjectOfClass:[NSString class] forKey:kUsernameCodingKey];
NSNumber *isNewUser = [aDecoder decodeObjectOfClass:[NSNumber class] forKey:kNewUserKey];
return [self initWithProviderID:providerID
profile:profile
username:username
isNewUser:isNewUser.boolValue];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_providerID forKey:kProviderIDCodingKey];
[aCoder encodeObject:_profile forKey:kProfileCodingKey];
[aCoder encodeObject:_username forKey:kUsernameCodingKey];
[aCoder encodeObject:[NSNumber numberWithBool:_newUser] forKey:kNewUserKey];
}
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAdditionalUserInfo.h"
NS_ASSUME_NONNULL_BEGIN
@interface FIRAdditionalUserInfo () <NSSecureCoding>
/** @fn userInfoWithVerifyAssertionResponse:
@brief A convenience factory method for constructing a @c FIRAdditionalUserInfo instance from
data returned by the verifyAssertion endpoint.
@param verifyAssertionResponse Data returned by the verifyAssertion endpoint.
@return A new instance of @c FIRAdditionalUserInfo using data from the verifyAssertion endpoint.
*/
+ (nullable instancetype)userInfoWithVerifyAssertionResponse:
(FIRVerifyAssertionResponse *)verifyAssertionResponse;
/** @fn initWithProviderID:profile:username:
@brief Designated initializer.
@param providerID The provider identifier.
@param profile Dictionary containing the additional IdP specific information.
@param username The name of the user.
@param isNewUser Indicates whether or not the current user was signed in for the first time.
*/
- (nullable instancetype)initWithProviderID:(nullable NSString *)providerID
profile:(nullable NSDictionary<NSString *, NSObject *> *)profile
username:(nullable NSString *)username
isNewUser:(BOOL)isNewUser NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthAPNSTokenType.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIRAuthAPNSToken
@brief A data structure for an APNs token.
*/
@interface FIRAuthAPNSToken : NSObject
/** @property data
@brief The APNs token data.
*/
@property(nonatomic, strong, readonly) NSData *data;
/** @property string
@brief The uppercase hexadecimal string form of the APNs token data.
*/
@property(nonatomic, strong, readonly) NSString *string;
/** @property type
@brief The APNs token type.
*/
@property(nonatomic, assign, readonly) FIRAuthAPNSTokenType type;
/** @fn initWithData:type:
@brief Initializes the instance.
@param data The APNs token data.
@param type The APNs token type.
@return The initialized instance.
*/
- (instancetype)initWithData:(NSData *)data type:(FIRAuthAPNSTokenType)type
NS_DESIGNATED_INITIALIZER;
/** @fn init
@brief Call @c initWithData:type: to get an instance of this class.
*/
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthAPNSToken.h"
NS_ASSUME_NONNULL_BEGIN
@implementation FIRAuthAPNSToken {
/** @var _string
@brief The lazy-initialized string form of the token data.
*/
NSString *_string;
}
- (instancetype)initWithData:(NSData *)data type:(FIRAuthAPNSTokenType)type {
self = [super init];
if (self) {
_data = [data copy];
_type = type;
}
return self;
}
- (NSString *)string {
if (!_string) {
NSUInteger capacity = _data.length * 2;
NSMutableString *tokenString = [NSMutableString stringWithCapacity:capacity];
const unsigned char *tokenData = _data.bytes;
for (int idx = 0; idx < _data.length; ++idx) {
[tokenString appendFormat:@"%02X", (int)tokenData[idx]];
}
_string = tokenString;
}
return _string;
}
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class FIRAuthAPNSToken;
NS_ASSUME_NONNULL_BEGIN
/** @typedef FIRAuthAPNSTokenCallback
@brief The type of block to receive an APNs token.
@param token The APNs token if one is available.
@param error The error happened if any.
@remarks Both `token` and `error` being `nil` means the request timed-out.
*/
typedef void (^FIRAuthAPNSTokenCallback)(FIRAuthAPNSToken *_Nullable token,
NSError *_Nullable error);
/** @class FIRAuthAPNSTokenManager
@brief A class to manage APNs token in memory.
*/
@interface FIRAuthAPNSTokenManager : NSObject
/** @property token
@brief The APNs token, if one is available.
@remarks Setting a token with FIRAuthAPNSTokenTypeUnknown will automatically converts it to
a token with the automatically detected type.
*/
@property(nonatomic, strong, nullable) FIRAuthAPNSToken *token;
/** @property timeout
@brief The timeout for registering for remote notification.
@remarks Only tests should access this property.
*/
@property(nonatomic, assign) NSTimeInterval timeout;
/** @fn init
@brief Call @c initWithApplication: to initialize an instance of this class.
*/
- (instancetype)init NS_UNAVAILABLE;
/** @fn initWithApplication:bundle
@brief Initializes the instance.
@param application The @c UIApplication to request the token from.
@return The initialized instance.
*/
- (instancetype)initWithApplication:(UIApplication *)application NS_DESIGNATED_INITIALIZER;
/** @fn getTokenWithCallback:
@brief Attempts to get the APNs token.
@param callback The block to be called either immediately or in future, either when a token
becomes available, or when timeout occurs, whichever happens earlier.
*/
- (void)getTokenWithCallback:(FIRAuthAPNSTokenCallback)callback;
/** @fn cancelWithError:
@brief Cancels any pending `getTokenWithCallback:` request.
@param error The error to return.
*/
- (void)cancelWithError:(NSError *)error;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthAPNSTokenManager.h"
#import <FirebaseCore/FIRLogger.h>
#import "FIRAuthAPNSToken.h"
#import "FIRAuthGlobalWorkQueue.h"
NS_ASSUME_NONNULL_BEGIN
/** @var kRegistrationTimeout
@brief Timeout for registration for remote notification.
@remarks Once we start to handle `application:didFailToRegisterForRemoteNotificationsWithError:`
we probably don't have to use timeout at all.
*/
static const NSTimeInterval kRegistrationTimeout = 5;
/** @var kLegacyRegistrationTimeout
@brief Timeout for registration for remote notification on iOS 7.
*/
static const NSTimeInterval kLegacyRegistrationTimeout = 30;
@implementation FIRAuthAPNSTokenManager {
/** @var _application
@brief The @c UIApplication to request the token from.
*/
UIApplication *_application;
/** @var _pendingCallbacks
@brief The list of all pending callbacks for the APNs token.
*/
NSMutableArray<FIRAuthAPNSTokenCallback> *_pendingCallbacks;
}
- (instancetype)initWithApplication:(UIApplication *)application {
self = [super init];
if (self) {
_application = application;
_timeout = [_application respondsToSelector:@selector(registerForRemoteNotifications)] ?
kRegistrationTimeout : kLegacyRegistrationTimeout;
}
return self;
}
- (void)getTokenWithCallback:(FIRAuthAPNSTokenCallback)callback {
if (_token) {
callback(_token, nil);
return;
}
if (_pendingCallbacks) {
[_pendingCallbacks addObject:callback];
return;
}
_pendingCallbacks =
[[NSMutableArray<FIRAuthAPNSTokenCallback> alloc] initWithObjects:callback, nil];
dispatch_async(dispatch_get_main_queue(), ^{
if ([self->_application respondsToSelector:@selector(registerForRemoteNotifications)]) {
[self->_application registerForRemoteNotifications];
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#if TARGET_OS_IOS
[self->_application registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert];
#endif // TARGET_OS_IOS
#pragma clang diagnostic pop
}
});
NSArray<FIRAuthAPNSTokenCallback> *applicableCallbacks = _pendingCallbacks;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_timeout * NSEC_PER_SEC)),
FIRAuthGlobalWorkQueue(), ^{
// Only cancel if the pending callbacks remain the same, i.e., not triggered yet.
if (applicableCallbacks == self->_pendingCallbacks) {
[self callBackWithToken:nil error:nil];
}
});
}
- (void)setToken:(nullable FIRAuthAPNSToken *)token {
if (!token) {
_token = nil;
return;
}
if (token.type == FIRAuthAPNSTokenTypeUnknown) {
static FIRAuthAPNSTokenType detectedTokenType = FIRAuthAPNSTokenTypeUnknown;
if (detectedTokenType == FIRAuthAPNSTokenTypeUnknown) {
detectedTokenType =
[[self class] isProductionApp] ? FIRAuthAPNSTokenTypeProd : FIRAuthAPNSTokenTypeSandbox;
}
token = [[FIRAuthAPNSToken alloc] initWithData:token.data type:detectedTokenType];
}
_token = token;
[self callBackWithToken:token error:nil];
}
- (void)cancelWithError:(NSError *)error {
[self callBackWithToken:nil error:error];
}
#pragma mark - Internal methods
/** @fn callBack
@brief Calls back all pending callbacks with APNs token or error.
@param token The APNs token if one is available.
@param error The error occurred, if any.
*/
- (void)callBackWithToken:(nullable FIRAuthAPNSToken *)token error:(nullable NSError *)error {
if (!_pendingCallbacks) {
return;
}
NSArray<FIRAuthAPNSTokenCallback> *allCallbacks = _pendingCallbacks;
_pendingCallbacks = nil;
for (FIRAuthAPNSTokenCallback callback in allCallbacks) {
callback(token, error);
}
};
/** @fn isProductionApp
@brief Whether or not the app has production (versus sandbox) provisioning profile.
@remarks This method is adapted from @c FIRInstanceID .
*/
+ (BOOL)isProductionApp {
const BOOL defaultAppTypeProd = YES;
NSError *error = nil;
Class envClass = NSClassFromString(@"FIRAppEnvironmentUtil");
SEL isSimulatorSelector = NSSelectorFromString(@"isSimulator");
if ([envClass respondsToSelector:isSimulatorSelector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
if ([envClass performSelector:isSimulatorSelector]) {
#pragma clang diagnostic pop
FIRLogInfo(kFIRLoggerAuth, @"I-AUT000006",
@"Assuming prod APNs token type on simulator.");
return defaultAppTypeProd;
}
}
NSString *path = [[[NSBundle mainBundle] bundlePath]
stringByAppendingPathComponent:@"embedded.mobileprovision"];
// Apps distributed via AppStore or TestFlight use the Production APNS certificates.
SEL isFromAppStoreSelector = NSSelectorFromString(@"isFromAppStore");
if ([envClass respondsToSelector:isFromAppStoreSelector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
if ([envClass performSelector:isFromAppStoreSelector]) {
#pragma clang diagnostic pop
return defaultAppTypeProd;
}
}
SEL isAppStoreReceiptSandboxSelector = NSSelectorFromString(@"isAppStoreReceiptSandbox");
if ([envClass respondsToSelector:isAppStoreReceiptSandboxSelector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
if ([envClass performSelector:isAppStoreReceiptSandboxSelector] && !path.length) {
#pragma clang diagnostic pop
// Distributed via TestFlight
return defaultAppTypeProd;
}
}
NSMutableData *profileData = [NSMutableData dataWithContentsOfFile:path options:0 error:&error];
if (!profileData.length || error) {
FIRLogInfo(kFIRLoggerAuth, @"I-AUT000007",
@"Error while reading embedded mobileprovision %@", error);
return defaultAppTypeProd;
}
// The "embedded.mobileprovision" sometimes contains characters with value 0, which signals the
// end of a c-string and halts the ASCII parser, or with value > 127, which violates strict 7-bit
// ASCII. Replace any 0s or invalid characters in the input.
uint8_t *profileBytes = (uint8_t *)profileData.bytes;
for (int i = 0; i < profileData.length; i++) {
uint8_t currentByte = profileBytes[i];
if (!currentByte || currentByte > 127) {
profileBytes[i] = '.';
}
}
NSString *embeddedProfile = [[NSString alloc] initWithBytesNoCopy:profileBytes
length:profileData.length
encoding:NSASCIIStringEncoding
freeWhenDone:NO];
if (error || !embeddedProfile.length) {
FIRLogInfo(kFIRLoggerAuth, @"I-AUT000008",
@"Error while reading embedded mobileprovision %@", error);
return defaultAppTypeProd;
}
NSScanner *scanner = [NSScanner scannerWithString:embeddedProfile];
NSString *plistContents;
if ([scanner scanUpToString:@"<plist" intoString:nil]) {
if ([scanner scanUpToString:@"</plist>" intoString:&plistContents]) {
plistContents = [plistContents stringByAppendingString:@"</plist>"];
}
}
if (!plistContents.length) {
return defaultAppTypeProd;
}
NSData *data = [plistContents dataUsingEncoding:NSUTF8StringEncoding];
if (!data.length) {
FIRLogInfo(kFIRLoggerAuth, @"I-AUT000009",
@"Couldn't read plist fetched from embedded mobileprovision");
return defaultAppTypeProd;
}
NSError *plistMapError;
id plistData = [NSPropertyListSerialization propertyListWithData:data
options:NSPropertyListImmutable
format:nil
error:&plistMapError];
if (plistMapError || ![plistData isKindOfClass:[NSDictionary class]]) {
FIRLogInfo(kFIRLoggerAuth, @"I-AUT000010",
@"Error while converting assumed plist to dict %@",
plistMapError.localizedDescription);
return defaultAppTypeProd;
}
NSDictionary *plistMap = (NSDictionary *)plistData;
if ([plistMap valueForKeyPath:@"ProvisionedDevices"]) {
FIRLogInfo(kFIRLoggerAuth, @"I-AUT000011",
@"Provisioning profile has specifically provisioned devices, "
@"most likely a Dev profile.");
}
NSString *apsEnvironment = [plistMap valueForKeyPath:@"Entitlements.aps-environment"];
FIRLogDebug(kFIRLoggerAuth, @"I-AUT000012",
@"APNS Environment in profile: %@", apsEnvironment);
// No aps-environment in the profile.
if (!apsEnvironment.length) {
FIRLogInfo(kFIRLoggerAuth, @"I-AUT000013",
@"No aps-environment set. If testing on a device APNS is not "
@"correctly configured. Please recheck your provisioning profiles.");
return defaultAppTypeProd;
}
if ([apsEnvironment isEqualToString:@"development"]) {
return NO;
}
return defaultAppTypeProd;
}
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/** @class FIRAuthAppCredential
@brief A class represents a credential that proves the identity of the app.
*/
@interface FIRAuthAppCredential : NSObject <NSSecureCoding>
/** @property receipt
@brief The server acknowledgement of receiving client's claim of identity.
*/
@property(nonatomic, strong, readonly) NSString *receipt;
/** @property secret
@brief The secret that the client received from server via a trusted channel, if ever.
*/
@property(nonatomic, strong, readonly, nullable) NSString *secret;
/** @fn initWithReceipt:secret:
@brief Initializes the instance.
@param receipt The server acknowledgement of receiving client's claim of identity.
@param secret The secret that the client received from server via a trusted channel, if ever.
@return The initialized instance.
*/
- (instancetype)initWithReceipt:(NSString *)receipt secret:(nullable NSString *)secret
NS_DESIGNATED_INITIALIZER;
/** @fn init
@brief Call @c initWithReceipt:secret: to get an instance of this class.
*/
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthAppCredential.h"
NS_ASSUME_NONNULL_BEGIN
/** @var kReceiptKey
@brief The key used to encode the receipt property for NSSecureCoding.
*/
static NSString *const kReceiptKey = @"receipt";
/** @var kSecretKey
@brief The key used to encode the secret property for NSSecureCoding.
*/
static NSString *const kSecretKey = @"secret";
@implementation FIRAuthAppCredential
- (instancetype)initWithReceipt:(NSString *)receipt secret:(nullable NSString *)secret {
self = [super init];
if (self) {
_receipt = [receipt copy];
_secret = [secret copy];
}
return self;
}
#pragma mark - NSSecureCoding
+ (BOOL)supportsSecureCoding {
return YES;
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
NSString *receipt = [aDecoder decodeObjectOfClass:[NSString class] forKey:kReceiptKey];
if (!receipt) {
return nil;
}
NSString *secret = [aDecoder decodeObjectOfClass:[NSString class] forKey:kSecretKey];
return [self initWithReceipt:receipt secret:secret];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_receipt forKey:kReceiptKey];
[aCoder encodeObject:_secret forKey:kSecretKey];
}
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
@class FIRAuthAppCredential;
@class FIRAuthKeychain;
NS_ASSUME_NONNULL_BEGIN
/** @typedef FIRAuthAppCredentialCallback
@brief The type of block to receive an app crdential.
@param credential The best available app credential at the time.
*/
typedef void (^FIRAuthAppCredentialCallback)(FIRAuthAppCredential *credential);
/** @class FIRAuthAppCredentialManager
@brief A class to manage app credentials backed by iOS Keychain.
*/
@interface FIRAuthAppCredentialManager : NSObject
/** @property credential
@brief The full credential (which has a secret) to be used by the app, if one is available.
*/
@property(nonatomic, strong, readonly, nullable) FIRAuthAppCredential *credential;
/** @property maximumNumberOfPendingReceipts
@brief The maximum (but not necessarily the minimum) number of pending receipts to be kept.
@remarks Only tests should access this property.
*/
@property(nonatomic, assign, readonly) NSUInteger maximumNumberOfPendingReceipts;
/** @fn init
@brief Call @c initWithKeychain: to initialize an instance of this class.
*/
- (instancetype)init NS_UNAVAILABLE;
/** @fn initWithKeychain:
@brief Initializes the instance.
@param keychain The iOS Keychain storage to back up the app credential with.
@return The initialized instance.
*/
- (instancetype)initWithKeychain:(FIRAuthKeychain *)keychain NS_DESIGNATED_INITIALIZER;
/** @fn didStartVerificationWithReceipt:timeout:callback:
@brief Notifies that the app verification process has started.
@param receipt The receipt for verification.
@param timeout The timeout value for how long the callback is waited to be called.
@param callback The block to be called in future either when the verification finishes, or
when timeout occurs, whichever happens earlier.
*/
- (void)didStartVerificationWithReceipt:(NSString *)receipt
timeout:(NSTimeInterval)timeout
callback:(FIRAuthAppCredentialCallback)callback;
/** @fn canFinishVerificationWithReceipt:
@brief Attempts to finish verification.
@param receipt The receipt to match the original receipt obtained when verification started.
@param secret The secret to complete the verification.
@return Whether or not the receipt matches a pending verification, and finishes verification
if it does.
*/
- (BOOL)canFinishVerificationWithReceipt:(NSString *)receipt secret:(NSString *)secret;
/** @fn clearCredential
@brief Clears the saved credential, to be used in the case that it is rejected by the server.
*/
- (void)clearCredential;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthAppCredentialManager.h"
#import "FIRAuthAppCredential.h"
#import "FIRAuthGlobalWorkQueue.h"
#import "FIRAuthKeychain.h"
NS_ASSUME_NONNULL_BEGIN
/** @var kKeychainDataKey
@brief The keychain key for the data.
*/
static NSString *const kKeychainDataKey = @"app_credentials";
/** @var kFullCredentialKey
@brief The data key for the full app credential.
*/
static NSString *const kFullCredentialKey = @"full_credential";
/** @var kPendingReceiptsKey
@brief The data key for the array of pending receipts.
*/
static NSString *const kPendingReceiptsKey = @"pending_receipts";
/** @var kMaximumNumberOfPendingReceipts
@brief The maximum number of partial credentials kept by this class.
*/
static const NSUInteger kMaximumNumberOfPendingReceipts = 32;
@implementation FIRAuthAppCredentialManager {
/** @var _keychain
@brief The keychain for app credentials to load from and to save to.
*/
FIRAuthKeychain *_keychain;
/** @var _pendingReceipts
@brief A list of pending receipts sorted in the order they were recorded.
*/
NSMutableArray<NSString *> *_pendingReceipts;
/** @var _callbacksByReceipt
@brief A map from pending receipts to callbacks.
*/
NSMutableDictionary<NSString *, FIRAuthAppCredentialCallback> *_callbacksByReceipt;
}
- (instancetype)initWithKeychain:(FIRAuthKeychain *)keychain {
self = [super init];
if (self) {
_keychain = keychain;
// Load the credentials from keychain if possible.
NSError *error;
NSData *encodedData = [_keychain dataForKey:kKeychainDataKey error:&error];
if (!error && encodedData) {
NSKeyedUnarchiver *unarchiver =
[[NSKeyedUnarchiver alloc] initForReadingWithData:encodedData];
FIRAuthAppCredential *credential =
[unarchiver decodeObjectOfClass:[FIRAuthAppCredential class]
forKey:kFullCredentialKey];
if ([credential isKindOfClass:[FIRAuthAppCredential class]]) {
_credential = credential;
}
NSSet<Class> *allowedClasses =
[NSSet<Class> setWithObjects:[NSArray class], [NSString class], nil];
NSArray<NSString *> *pendingReceipts =
[unarchiver decodeObjectOfClasses:allowedClasses forKey:kPendingReceiptsKey];
if ([pendingReceipts isKindOfClass:[NSArray class]]) {
_pendingReceipts = [pendingReceipts mutableCopy];
}
}
if (!_pendingReceipts) {
_pendingReceipts = [[NSMutableArray<NSString *> alloc] init];
}
_callbacksByReceipt =
[[NSMutableDictionary<NSString *, FIRAuthAppCredentialCallback> alloc] init];
}
return self;
}
- (NSUInteger)maximumNumberOfPendingReceipts {
return kMaximumNumberOfPendingReceipts;
}
- (void)didStartVerificationWithReceipt:(NSString *)receipt
timeout:(NSTimeInterval)timeout
callback:(FIRAuthAppCredentialCallback)callback {
[_pendingReceipts removeObject:receipt];
if (_pendingReceipts.count >= kMaximumNumberOfPendingReceipts) {
[_pendingReceipts removeObjectAtIndex:0];
}
[_pendingReceipts addObject:receipt];
_callbacksByReceipt[receipt] = callback;
[self saveData];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC)),
FIRAuthGlobalWorkQueue(), ^{
[self callBackWithReceipt:receipt];
});
}
- (BOOL)canFinishVerificationWithReceipt:(NSString *)receipt secret:(NSString *)secret {
if (![_pendingReceipts containsObject:receipt]) {
return NO;
}
[_pendingReceipts removeObject:receipt];
_credential = [[FIRAuthAppCredential alloc] initWithReceipt:receipt secret:secret];
[self saveData];
[self callBackWithReceipt:receipt];
return YES;
}
- (void)clearCredential {
_credential = nil;
[self saveData];
}
#pragma mark - Internal methods
/** @fn saveData
@brief Save the data in memory to the keychain ignoring any errors.
*/
- (void)saveData {
NSMutableData *archiveData = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:archiveData];
[archiver encodeObject:_credential forKey:kFullCredentialKey];
[archiver encodeObject:_pendingReceipts forKey:kPendingReceiptsKey];
[archiver finishEncoding];
[_keychain setData:archiveData forKey:kKeychainDataKey error:NULL];
}
/** @fn callBackWithReceipt:
@brief Calls the saved callback for the specifc receipt.
@param receipt The receipt associated with the callback.
*/
- (void)callBackWithReceipt:(NSString *)receipt {
FIRAuthAppCredentialCallback callback = _callbacksByReceipt[receipt];
if (!callback) {
return;
}
[_callbacksByReceipt removeObjectForKey:receipt];
if (_credential) {
callback(_credential);
} else {
callback([[FIRAuthAppCredential alloc] initWithReceipt:receipt secret:nil]);
}
}
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/** @protocol FIRAuthAppDelegateHandler
@brief The protocol to handle app delegate methods.
*/
@protocol FIRAuthAppDelegateHandler <NSObject>
/** @fn setAPNSToken:
@brief Sets the APNs device token.
@param token The APNs device token.
*/
- (void)setAPNSToken:(NSData *)token;
/** @fn handleAPNSTokenError:
@brief Handles APNs device token error.
@param error The APNs device token error.
*/
- (void)handleAPNSTokenError:(NSError *)error;
/** @fn canHandleNotification:
@brief Checks whether the notification can be handled by the receiver, and handles it if so.
@param notification The notification in question, which will be consumed if returns @c YES.
@return Whether the notification can be (and already has been) handled by the receiver.
*/
- (BOOL)canHandleNotification:(nonnull NSDictionary *)notification;
/** @fn canHandleURL:
@brief Checks whether the URL can be handled by the receiver, and handles it if so.
@param url The URL in question, which will be consumed if returns @c YES.
@return Whether the URL can be (and already has been) handled by the receiver.
*/
- (BOOL)canHandleURL:(nonnull NSURL *)url;
@end
/** @class FIRAuthAppDelegateProxy
@brief A manager for swizzling @c UIApplicationDelegate methods.
*/
@interface FIRAuthAppDelegateProxy : NSObject
/** @fn initWithApplication
@brief Initialize the instance with the given @c UIApplication.
@returns An initialized instance, or @c nil if a proxy cannot be established.
@remarks This method should only be called from tests if called outside of this class.
*/
- (nullable instancetype)initWithApplication:(nullable UIApplication *)application
NS_DESIGNATED_INITIALIZER;
/** @fn init
@brief Call @c sharedInstance to get an instance of this class.
*/
- (instancetype)init NS_UNAVAILABLE;
/** @fn addHandler:
@brief Adds a handler for UIApplicationDelegate methods.
@param handler The handler to be added.
*/
- (void)addHandler:(__weak id<FIRAuthAppDelegateHandler>)handler;
/** @fn sharedInstance
@brief Gets the shared instance of this class.
@returns The shared instance of this class.
*/
+ (nullable instancetype)sharedInstance;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthCredential_Internal.h"
@implementation FIRAuthCredential
- (instancetype)init {
@throw [NSException exceptionWithName:@"Attempt to call unavailable initializer."
reason:@"This class is an abstract base class. It's init method "
"should not be called directly."
userInfo:nil];
}
- (nullable instancetype)initWithProvider:(NSString *)provider {
self = [super init];
if (self) {
_provider = [provider copy];
}
return self;
}
- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request {
@throw [NSException exceptionWithName:@"Attempt to call virtual method."
reason:@"This method must be overridden by a subclass."
userInfo:nil];
}
@end
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthCredential.h"
@class FIRVerifyAssertionRequest;
NS_ASSUME_NONNULL_BEGIN
@interface FIRAuthCredential ()
/** @fn initWithProvider:
@brief Designated initializer.
@remarks This is the designated initializer for internal/friend subclasses.
@param provider The provider name.
*/
- (nullable instancetype)initWithProvider:(NSString *)provider NS_DESIGNATED_INITIALIZER;
/** @fn prepareVerifyAssertionRequest:
@brief Called immediately before a request to the verifyAssertion endpoint is made. Implementers
should update the passed request instance with their credentials.
@param request The request to be updated with credentials.
*/
- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthDataResult_Internal.h"
#import "FIRAdditionalUserInfo.h"
#import "FIRUser.h"
NS_ASSUME_NONNULL_BEGIN
@implementation FIRAuthDataResult
/** @var kAdditionalUserInfoCodingKey
@brief The key used to encode the additionalUserInfo property for NSSecureCoding.
*/
static NSString *const kAdditionalUserInfoCodingKey = @"additionalUserInfo";
/** @var kUserCodingKey
@brief The key used to encode the user property for NSSecureCoding.
*/
static NSString *const kUserCodingKey = @"user";
- (nullable instancetype)initWithUser:(FIRUser *)user
additionalUserInfo:(nullable FIRAdditionalUserInfo *)additionalUserInfo {
self = [super init];
if (self) {
_additionalUserInfo = additionalUserInfo;
_user = user;
}
return self;
}
#pragma mark - NSSecureCoding
+ (BOOL)supportsSecureCoding {
return YES;
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
FIRUser *user =
[aDecoder decodeObjectOfClass:[FIRUser class] forKey:kUserCodingKey];
FIRAdditionalUserInfo *additionalUserInfo =
[aDecoder decodeObjectOfClass:[FIRAdditionalUserInfo class]
forKey:kAdditionalUserInfoCodingKey];
return [self initWithUser:user additionalUserInfo:additionalUserInfo];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_user forKey:kUserCodingKey];
[aCoder encodeObject:_additionalUserInfo forKey:kAdditionalUserInfoCodingKey];
}
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthDataResult.h"
NS_ASSUME_NONNULL_BEGIN
@interface FIRAuthDataResult () <NSSecureCoding>
/** @fn initWithUser:additionalUserInfo:
@brief Designated initializer.
@param user The signed in user reference.
@param additionalUserInfo The additional user info if available.
*/
- (nullable instancetype)initWithUser:(FIRUser *)user
additionalUserInfo:(nullable FIRAdditionalUserInfo *)additionalUserInfo
NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRAuthUIDelegate.h"
NS_ASSUME_NONNULL_BEGIN
/** @class FIRAuthDefaultUIDelegate
@brief Class responsible for providing a default FIRAuthUIDelegte.
@remarks This class should be used in the case that a UIDelegate was expected and necessary to
continue a given flow, but none was provided.
*/
@interface FIRAuthDefaultUIDelegate : NSObject <FIRAuthUIDelegate>
/** @fn defaultUIDelegate
@brief Unavailable. Please use @c +defaultUIDelegate:
*/
- (instancetype)init NS_UNAVAILABLE;
/** @fn defaultUIDelegate
@brief Returns a default FIRAuthUIDelegate object.
@return The default FIRAuthUIDelegate object.
*/
+ (id<FIRAuthUIDelegate>)defaultUIDelegate;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthDefaultUIDelegate.h"
NS_ASSUME_NONNULL_BEGIN
@interface FIRAuthDefaultUIDelegate ()
/** @fn initWithViewController:
@brief Initializes the instance with a view controller.
@param viewController The view controller as the presenting view controller in @c
FIRAuthUIDelegate.
@return The initialized instance.
*/
- (instancetype)initWithViewController:(UIViewController *)viewController NS_DESIGNATED_INITIALIZER;
@end
@implementation FIRAuthDefaultUIDelegate {
/** @var _viewController
@brief The presenting view controller.
*/
UIViewController *_viewController;
}
- (instancetype)initWithViewController:(UIViewController *)viewController {
self = [super init];
if (self) {
_viewController = viewController;
}
return self;
}
- (void)presentViewController:(UIViewController *)viewControllerToPresent
animated:(BOOL)flag
completion:(nullable void (^)(void))completion {
[_viewController presentViewController:viewControllerToPresent
animated:flag
completion:completion];
}
- (void)dismissViewControllerAnimated:(BOOL)flag completion:(nullable void (^)(void))completion {
[_viewController dismissViewControllerAnimated:flag completion:completion];
}
+ (id<FIRAuthUIDelegate>)defaultUIDelegate {
UIViewController *topViewController =
[UIApplication sharedApplication].keyWindow.rootViewController;
while (true){
if (topViewController.presentedViewController) {
topViewController = topViewController.presentedViewController;
} else if ([topViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *nav = (UINavigationController *)topViewController;
topViewController = nav.topViewController;
} else if ([topViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController *tab = (UITabBarController *)topViewController;
topViewController = tab.selectedViewController;
} else {
break;
}
}
return [[FIRAuthDefaultUIDelegate alloc] initWithViewController:topViewController];
}
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/** @typedef FIRAuthDispatcherImplBlock
@brief The type of block which can be set as the implementation for @c
dispatchAfterDelay:queue:callback: .
@param delay The delay in seconds after which the task will be scheduled to execute.
@param queue The dispatch queue on which the task will be submitted.
@param task The task (block) to be scheduled for future execution.
*/
typedef void(^FIRAuthDispatcherImplBlock)(NSTimeInterval delay,
dispatch_queue_t queue,
void (^task)(void));
/** @class FIRAuthDispatchAfter
@brief A utility class used to facilitate scheduling tasks to be executed in the future.
*/
@interface FIRAuthDispatcher : NSObject
/** @property dispatchAfterImplementation
@brief Allows custom implementation of dispatchAfterDelay:queue:callback:.
@remarks Set to nil to restore default implementation.
*/
@property(nonatomic, nullable, copy) FIRAuthDispatcherImplBlock dispatchAfterImplementation;
/** @fn dispatchAfterDelay:queue:callback:
@brief Schedules task in the future after a specified delay.
@param delay The delay in seconds after which the task will be scheduled to execute.
@param queue The dispatch queue on which the task will be submitted.
@param task The task (block) to be scheduled for future execution.
*/
- (void)dispatchAfterDelay:(NSTimeInterval)delay
queue:(dispatch_queue_t)queue
task:(void (^)(void))task;
/** @fn sharedInstance
@brief Gets the shared instance of this class.
@returns The shared instance of this clss
*/
+ (instancetype)sharedInstance;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthDispatcher.h"
NS_ASSUME_NONNULL_BEGIN
@implementation FIRAuthDispatcher
@synthesize dispatchAfterImplementation = _dispatchAfterImplementation;
+ (instancetype)sharedInstance {
static dispatch_once_t onceToken;
static FIRAuthDispatcher *sharedInstance;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
- (void)dispatchAfterDelay:(NSTimeInterval)delay
queue:(dispatch_queue_t)queue
task:(void (^)(void))task {
if (_dispatchAfterImplementation) {
_dispatchAfterImplementation(delay, queue, task);
return;
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC), queue, task);
}
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/** @class FIRAuthExceptionUtils
@brief Utility class used to raise standardized Auth related exceptions.
*/
@interface FIRAuthExceptionUtils : NSObject
/** @fn raiseInvalidParameterExceptionWithReason:
@brief raises the "invalid parameter" exception
@param reason string will contain a description of the error.
*/
+ (void)raiseInvalidParameterExceptionWithReason:(nullable NSString *)reason;
/** @fn raiseMethodNotImplementedExceptionWithReason:
@brief raises the "method not implemented" exception
@param reason string will contain a description of the error.
@see FIRMethodNotImplementedException
*/
+ (void)raiseMethodNotImplementedExceptionWithReason:(nullable NSString *)reason;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthExceptionUtils.h"
/** @var FIRMethodNotImplementedException
@brief The name of the "Method Not Implemented" exception.
*/
static NSString *const FIRMethodNotImplementedException = @"FIRMethodNotImplementedException";
@implementation FIRAuthExceptionUtils
+ (void)raiseInvalidParameterExceptionWithReason:(NSString *)reason {
[NSException raise:NSInvalidArgumentException format:@"%@", reason];
}
+ (void)raiseMethodNotImplementedExceptionWithReason:(nullable NSString *)reason {
NSException *exception =
[NSException exceptionWithName:FIRMethodNotImplementedException reason:reason userInfo:nil];
[exception raise];
}
@end
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/** @fn FIRAuthGlobalWorkQueue
@brief Retrieves the global serial work queue for Firebase Auth.
@return The global serial dispatch queue.
@remarks To ensure thread safety, all auth code must be executed in either this global work
queue, or a serial queue that has its target queue set to this work queue. All public method
implementations that may involve contested code shall dispatch to this work queue as the
first thing they do.
*/
extern dispatch_queue_t FIRAuthGlobalWorkQueue(void);
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthGlobalWorkQueue.h"
dispatch_queue_t FIRAuthGlobalWorkQueue() {
static dispatch_once_t once;
static dispatch_queue_t queue;
dispatch_once(&once, ^{
queue = dispatch_queue_create("com.google.firebase.auth.globalWorkQueue", NULL);
});
return queue;
}
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
@brief The protocol for permanant data storage.
*/
@protocol FIRAuthStorage <NSObject>
/** @fn initWithService:
@brief Initialize a @c FIRAuthStorage instance.
@param service The name of the storage service to use.
@return An initialized @c FIRAuthStorage instance for the specified service.
*/
- (id<FIRAuthStorage>)initWithService:(NSString *)service;
/** @fn dataForKey:error:
@brief Gets the data for @c key in the storage. The key is set for the attribute
@c kSecAttrAccount of a generic password query.
@param key The key to use.
@param error The address to store any error that occurs during the process, if not NULL.
If the operation was successful, its content is set to @c nil .
@return The data stored in the storage for @c key, if any.
*/
- (nullable NSData *)dataForKey:(NSString *)key error:(NSError **_Nullable)error;
/** @fn setData:forKey:error:
@brief Sets the data for @c key in the storage. The key is set for the attribute
@c kSecAttrAccount of a generic password query.
@param data The data to store.
@param key The key to use.
@param error The address to store any error that occurs during the process, if not NULL.
@return Whether the operation succeeded or not.
*/
- (BOOL)setData:(NSData *)data forKey:(NSString *)key error:(NSError **_Nullable)error;
/** @fn removeDataForKey:error:
@brief Removes the data for @c key in the storage. The key is set for the attribute
@c kSecAttrAccount of a generic password query.
@param key The key to use.
@param error The address to store any error that occurs during the process, if not NULL.
@return Whether the operation succeeded or not.
*/
- (BOOL)removeDataForKey:(NSString *)key error:(NSError **_Nullable)error;
@end
/** @class FIRAuthKeychain
@brief The utility class to manipulate data in iOS Keychain.
*/
@interface FIRAuthKeychain : NSObject <FIRAuthStorage>
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthKeychain.h"
#import <Security/Security.h>
#import "FIRAuthErrorUtils.h"
#import "FIRAuthUserDefaultsStorage.h"
#if FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE
#import <UIKit/UIKit.h>
/** @var kOSVersionMatcherForUsingUserDefaults
@brief The regular expression to match all OS versions that @c FIRAuthUserDefaultsStorage is
used instead if available.
*/
static NSString *const kOSVersionMatcherForUsingUserDefaults = @"^10\\.[01](\\..*)?$";
#endif // FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE
/** @var kAccountPrefix
@brief The prefix string for keychain item account attribute before the key.
@remarks A number "1" is encoded in the prefix in case we need to upgrade the scheme in future.
*/
static NSString *const kAccountPrefix = @"firebase_auth_1_";
@implementation FIRAuthKeychain {
/** @var _service
@brief The name of the keychain service.
*/
NSString *_service;
/** @var _legacyItemDeletedForKey
@brief Indicates whether or not this class knows that the legacy item for a particular key has
been deleted.
@remarks This dictionary is to avoid unecessary keychain operations against legacy items.
*/
NSMutableDictionary *_legacyEntryDeletedForKey;
}
- (id<FIRAuthStorage>)initWithService:(NSString *)service {
#if FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE
NSString *OSVersion = [UIDevice currentDevice].systemVersion;
NSRegularExpression *regex =
[NSRegularExpression regularExpressionWithPattern:kOSVersionMatcherForUsingUserDefaults
options:0
error:NULL];
if ([regex numberOfMatchesInString:OSVersion options:0 range:NSMakeRange(0, OSVersion.length)]) {
return (id<FIRAuthStorage>)[[FIRAuthUserDefaultsStorage alloc] initWithService:service];
}
#endif // FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE
self = [super init];
if (self) {
_service = [service copy];
_legacyEntryDeletedForKey = [[NSMutableDictionary alloc] init];
}
return self;
}
- (NSData *)dataForKey:(NSString *)key error:(NSError **_Nullable)error {
if (!key.length) {
[NSException raise:NSInvalidArgumentException
format:@"%@", @"The key cannot be nil or empty."];
return nil;
}
NSData *data = [self itemWithQuery:[self genericPasswordQueryWithKey:key] error:error];
if (error && *error) {
return nil;
}
if (data) {
return data;
}
// Check for legacy form.
if (_legacyEntryDeletedForKey[key]) {
return nil;
}
data = [self itemWithQuery:[self legacyGenericPasswordQueryWithKey:key] error:error];
if (error && *error) {
return nil;
}
if (!data) {
// Mark legacy data as non-existing so we don't have to query it again.
_legacyEntryDeletedForKey[key] = @YES;
return nil;
}
// Move the data to current form.
if (![self setData:data forKey:key error:error]) {
return nil;
}
[self deleteLegacyItemWithKey:key];
return data;
}
- (BOOL)setData:(NSData *)data forKey:(NSString *)key error:(NSError **_Nullable)error {
if (!key.length) {
[NSException raise:NSInvalidArgumentException
format:@"%@", @"The key cannot be nil or empty."];
return NO;
}
NSDictionary *attributes = @{
(__bridge id)kSecValueData : data,
(__bridge id)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
};
return [self setItemWithQuery:[self genericPasswordQueryWithKey:key]
attributes:attributes
error:error];
}
- (BOOL)removeDataForKey:(NSString *)key error:(NSError **_Nullable)error {
if (!key.length) {
[NSException raise:NSInvalidArgumentException
format:@"%@", @"The key cannot be nil or empty."];
return NO;
}
if (![self deleteItemWithQuery:[self genericPasswordQueryWithKey:key] error:error]) {
return NO;
}
// Legacy form item, if exists, also needs to be removed, otherwise it will be exposed when
// current form item is removed, leading to incorrect semantics.
[self deleteLegacyItemWithKey:key];
return YES;
}
#pragma mark - Private
- (NSData *)itemWithQuery:(NSDictionary *)query error:(NSError **_Nullable)error {
NSMutableDictionary *returningQuery = [query mutableCopy];
returningQuery[(__bridge id)kSecReturnData] = @YES;
returningQuery[(__bridge id)kSecReturnAttributes] = @YES;
// Using a match limit of 2 means that we can check whether there is more than one item.
// If we used a match limit of 1 we would never find out.
returningQuery[(__bridge id)kSecMatchLimit] = @2;
CFArrayRef result = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)returningQuery,
(CFTypeRef *)&result);
if (status == noErr && result != NULL) {
NSArray *items = (__bridge_transfer NSArray *)result;
if (items.count != 1) {
if (error) {
*error = [FIRAuthErrorUtils keychainErrorWithFunction:@"SecItemCopyMatching"
status:status];
}
return nil;
}
if (error) {
*error = nil;
}
NSDictionary *item = items[0];
return item[(__bridge id)kSecValueData];
}
if (status == errSecItemNotFound) {
if (error) {
*error = nil;
}
} else {
if (error) {
*error = [FIRAuthErrorUtils keychainErrorWithFunction:@"SecItemCopyMatching" status:status];
}
}
return nil;
}
- (BOOL)setItemWithQuery:(NSDictionary *)query
attributes:(NSDictionary *)attributes
error:(NSError **_Nullable)error {
NSMutableDictionary *combined = [attributes mutableCopy];
[combined addEntriesFromDictionary:query];
BOOL hasItem = NO;
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)combined, NULL);
if (status == errSecDuplicateItem) {
hasItem = YES;
status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)attributes);
}
if (status == noErr) {
return YES;
}
if (error) {
NSString *function = hasItem ? @"SecItemUpdate" : @"SecItemAdd";
*error = [FIRAuthErrorUtils keychainErrorWithFunction:function status:status];
}
return NO;
}
- (BOOL)deleteItemWithQuery:(NSDictionary *)query error:(NSError **_Nullable)error {
OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query);
if (status == noErr || status == errSecItemNotFound) {
return YES;
}
if (error) {
*error = [FIRAuthErrorUtils keychainErrorWithFunction:@"SecItemDelete" status:status];
}
return NO;
}
/** @fn deleteLegacyItemsWithKey:
@brief Deletes legacy item from the keychain if it is not already known to be deleted.
@param key The key for the item.
*/
- (void)deleteLegacyItemWithKey:(NSString *)key {
if (_legacyEntryDeletedForKey[key]) {
return;
}
NSDictionary *query = [self legacyGenericPasswordQueryWithKey:key];
SecItemDelete((__bridge CFDictionaryRef)query);
_legacyEntryDeletedForKey[key] = @YES;
}
/** @fn genericPasswordQueryWithKey:
@brief Returns a keychain query of generic password to be used to manipulate key'ed value.
@param key The key for the value being manipulated, used as the account field in the query.
*/
- (NSDictionary *)genericPasswordQueryWithKey:(NSString *)key {
return @{
(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrAccount : [kAccountPrefix stringByAppendingString:key],
(__bridge id)kSecAttrService : _service,
};
}
/** @fn legacyGenericPasswordQueryWithKey:
@brief Returns a keychain query of generic password without service field, which is used by
previous version of this class.
@param key The key for the value being manipulated, used as the account field in the query.
*/
- (NSDictionary *)legacyGenericPasswordQueryWithKey:(NSString *)key {
return @{
(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrAccount : key,
};
}
@end
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class FIRAuthAppCredentialManager;
NS_ASSUME_NONNULL_BEGIN
/** @typedef FIRAuthNotificationForwardingCallback
@brief The type of block to receive whether or not remote notifications are being forwarded.
@param isNotificationBeingForwarded Whether or not remote notifications are being forwarded.
*/
typedef void (^FIRAuthNotificationForwardingCallback)(BOOL isNotificationBeingForwarded);
/** @class FIRAuthNotificationManager
*/
@interface FIRAuthNotificationManager : NSObject
/** @property timeout
@brief The timeout for checking for notification forwarding.
@remarks Only tests should access this property.
*/
@property(nonatomic, assign) NSTimeInterval timeout;
/** @fn initWithApplication:appCredentialManager:
@brief Initializes the instance.
@param application The application.
@param appCredentialManager The object to handle app credentials delivered via notification.
@return The initialized instance.
*/
- (instancetype)initWithApplication:(UIApplication *)application
appCredentialManager:(FIRAuthAppCredentialManager *)appCredentialManager
NS_DESIGNATED_INITIALIZER;
/** @fn init
@brief please use initWithAppCredentialManager: instead.
*/
- (instancetype)init NS_UNAVAILABLE;
/** @fn checkNotificationForwardingWithCallback:
@brief Checks whether or not remote notifications are being forwarded to this class.
@param callback The block to be called either immediately or in future once a result
is available.
*/
- (void)checkNotificationForwardingWithCallback:(FIRAuthNotificationForwardingCallback)callback;
/** @fn canHandleNotification:
@brief Attempts to handle the remote notification.
@param notification The notification in question.
@return Whether or the notification has been handled.
*/
- (BOOL)canHandleNotification:(NSDictionary *)notification;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthNotificationManager.h"
#import <FirebaseCore/FIRLogger.h>
#import "FIRAuthAppCredential.h"
#import "FIRAuthAppCredentialManager.h"
#import "FIRAuthGlobalWorkQueue.h"
NS_ASSUME_NONNULL_BEGIN
/** @var kNotificationKey
@brief The key to locate payload data in the remote notification.
*/
static NSString *const kNotificationDataKey = @"com.google.firebase.auth";
/** @var kNotificationReceiptKey
@brief The key for the receipt in the remote notification payload data.
*/
static NSString *const kNotificationReceiptKey = @"receipt";
/** @var kNotificationSecretKey
@brief The key for the secret in the remote notification payload data.
*/
static NSString *const kNotificationSecretKey = @"secret";
/** @var kNotificationProberKey
@brief The key for marking the prober in the remote notification payload data.
*/
static NSString *const kNotificationProberKey = @"warning";
/** @var kProbingTimeout
@brief Timeout for probing whether the app delegate forwards the remote notification to us.
*/
static const NSTimeInterval kProbingTimeout = 1;
@implementation FIRAuthNotificationManager {
/** @var _application
@brief The application.
*/
UIApplication *_application;
/** @var _appCredentialManager
@brief The object to handle app credentials delivered via notification.
*/
FIRAuthAppCredentialManager *_appCredentialManager;
/** @var _hasCheckedNotificationForwarding
@brief Whether notification forwarding has been checked or not.
*/
BOOL _hasCheckedNotificationForwarding;
/** @var _isNotificationBeingForwarded
@brief Whether or not notification is being forwarded
*/
BOOL _isNotificationBeingForwarded;
/** @var _pendingCallbacks
@brief All pending callbacks while a check is being performed.
*/
NSMutableArray<FIRAuthNotificationForwardingCallback> *_pendingCallbacks;
}
- (instancetype)initWithApplication:(UIApplication *)application
appCredentialManager:(FIRAuthAppCredentialManager *)appCredentialManager {
self = [super init];
if (self) {
_application = application;
_appCredentialManager = appCredentialManager;
_timeout = kProbingTimeout;
}
return self;
}
- (void)checkNotificationForwardingWithCallback:(FIRAuthNotificationForwardingCallback)callback {
if (_pendingCallbacks) {
[_pendingCallbacks addObject:callback];
return;
}
if (_hasCheckedNotificationForwarding) {
callback(_isNotificationBeingForwarded);
return;
}
_hasCheckedNotificationForwarding = YES;
_pendingCallbacks =
[[NSMutableArray<FIRAuthNotificationForwardingCallback> alloc] initWithObjects:callback, nil];
dispatch_async(dispatch_get_main_queue(), ^{
NSDictionary *proberNotification = @{
kNotificationDataKey : @{
kNotificationProberKey : @"This fake notification should be forwarded to Firebase Auth."
}
};
if ([self->_application.delegate respondsToSelector:
@selector(application:didReceiveRemoteNotification:fetchCompletionHandler:)]) {
[self->_application.delegate application:self->_application
didReceiveRemoteNotification:proberNotification
fetchCompletionHandler:^(UIBackgroundFetchResult result) {}];
#if !TARGET_OS_TV
} else if ([self->_application.delegate respondsToSelector:
@selector(application:didReceiveRemoteNotification:)]) {
[self->_application.delegate application:self->_application
didReceiveRemoteNotification:proberNotification];
#endif
} else {
FIRLogWarning(kFIRLoggerAuth, @"I-AUT000015",
@"The UIApplicationDelegate must handle remote notification for phone number "
@"authentication to work.");
}
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_timeout * NSEC_PER_SEC)),
FIRAuthGlobalWorkQueue(), ^{
[self callBack];
});
}
- (BOOL)canHandleNotification:(NSDictionary *)notification {
NSDictionary *data = notification[kNotificationDataKey];
if ([data isKindOfClass:[NSString class]]) {
// Deserialize in case the data is a JSON string.
NSData *JSONData = [((NSString *)data) dataUsingEncoding:NSUTF8StringEncoding];
data = [NSJSONSerialization JSONObjectWithData:JSONData options:0 error:NULL];
}
if (![data isKindOfClass:[NSDictionary class]]) {
return NO;
}
if (data[kNotificationProberKey]) {
if (!_pendingCallbacks) {
// The prober notification probably comes from another instance, so pass it along.
return NO;
}
_isNotificationBeingForwarded = YES;
[self callBack];
return YES;
}
NSString *receipt = data[kNotificationReceiptKey];
if (![receipt isKindOfClass:[NSString class]]) {
return NO;
}
NSString *secret = data[kNotificationSecretKey];
if (![receipt isKindOfClass:[NSString class]]) {
return NO;
}
return [_appCredentialManager canFinishVerificationWithReceipt:receipt secret:secret];
}
#pragma mark - Internal methods
/** @fn callBack
@brief Calls back all pending callbacks with the result of notification forwarding check.
*/
- (void)callBack {
if (!_pendingCallbacks) {
return;
}
NSArray<FIRAuthNotificationForwardingCallback> *allCallbacks = _pendingCallbacks;
_pendingCallbacks = nil;
for (FIRAuthNotificationForwardingCallback callback in allCallbacks) {
callback(_isNotificationBeingForwarded);
}
};
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
@brief Indicates the type of operation performed for RPCs that support the operation
parameter.
*/
typedef NS_ENUM(NSInteger, FIRAuthOperationType) {
/** Indicates that the operation type is uspecified.
*/
FIRAuthOperationTypeUnspecified = 0,
/** Indicates that the operation type is sign in or sign up.
*/
FIRAuthOperationTypeSignUpOrSignIn = 1,
/** Indicates that the operation type is reauthentication.
*/
FIRAuthOperationTypeReauth = 2,
/** Indicates that the operation type is update.
*/
FIRAuthOperationTypeUpdate = 3,
/** Indicates that the operation type is link.
*/
FIRAuthOperationTypeLink = 4,
};
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#pragma mark - Provider ID constants
// Declared 'extern' in FIRGoogleAuthProvider.h
NSString *const FIRGoogleAuthProviderID = @"google.com";
// Declared 'extern' in FIRFacebookAuthProvider.h
NSString *const FIRFacebookAuthProviderID = @"facebook.com";
// Declared 'extern' in FIREmailAuthProvider.h
NSString *const FIREmailAuthProviderID = @"password";
// Declared 'extern' in FIREmailAuthProvider.h
NSString *const FIREmailPasswordAuthProviderID = @"password";
// Declared 'extern' in FIRTwitterAuthProvider.h
NSString *const FIRTwitterAuthProviderID = @"twitter.com";
// Declared 'extern' in FIRGitHubAuthProvider.h
NSString *const FIRGitHubAuthProviderID = @"github.com";
// Declared 'extern' in FIRPhoneAuthProvider.h
NSString *const FIRPhoneAuthProviderID = @"phone";
#pragma mark - sign-in methods constants
// Declared 'extern' in FIRGoogleAuthProvider.h
NSString *const FIRGoogleAuthSignInMethod = @"google.com";
// Declared 'extern' in FIREmailAuthProvider.h
NSString *const FIREmailPasswordAuthSignInMethod = @"password";
// Declared 'extern' in FIREmailAuthProvider.h
NSString *const FIREmailLinkAuthSignInMethod = @"emailLink";
// Declared 'extern' in FIRTwitterAuthProvider.h
NSString *const FIRTwitterAuthSignInMethod = @"twitter.com";
// Declared 'extern' in FIRFacebookAuthProvider.h
NSString *const FIRFacebookAuthSignInMethod = @"facebook.com";
// Declared 'extern' in FIRGitHubAuthProvider.h
NSString *const FIRGitHubAuthSignInMethod = @"github.com";
// Declared 'extern' in FIRPhoneAuthProvider.h
NSString *const FIRPhoneAuthSignInMethod = @"phone";
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/** @typedef FIRAuthSerialTaskCompletionBlock
@brief The type of method a @c FIRAuthSerialTask must call when it is complete.
*/
typedef void (^FIRAuthSerialTaskCompletionBlock)(void);
/** @typedef FIRAuthSerialTask
@brief Represents a unit of work submitted to a task queue.
@param complete The task MUST call the complete method when done.
*/
typedef void (^FIRAuthSerialTask)(FIRAuthSerialTaskCompletionBlock complete);
/** @class FIRAuthSerialTaskQueue
@brief An easy to use serial task queue which supports a callback-based completion notification
system for easy asyncronous call chaining.
*/
@interface FIRAuthSerialTaskQueue : NSObject
/** @fn enqueueTask:
@brief Enqueues a task for serial execution in the queue.
@remarks The task MUST call the complete method when done. This method is thread-safe.
The task block won't be executed concurrently with any other blocks in other task queues or
the global work queue as returned by @c FIRAuthGlobalWorkQueue , but an uncompleted task
(e.g. task block finished executation before complete method is called at a later time)
does not affect other task queues or the global work queue.
*/
- (void)enqueueTask:(FIRAuthSerialTask)task;
@end
NS_ASSUME_NONNULL_END
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthSerialTaskQueue.h"
#import "FIRAuthGlobalWorkQueue.h"
@implementation FIRAuthSerialTaskQueue {
/** @var _dispatchQueue
@brief The asyncronous dispatch queue into which tasks are enqueued and processed
serially.
*/
dispatch_queue_t _dispatchQueue;
}
- (instancetype)init {
self = [super init];
if (self) {
_dispatchQueue = dispatch_queue_create("com.google.firebase.auth.serialTaskQueue", NULL);
dispatch_set_target_queue(_dispatchQueue, FIRAuthGlobalWorkQueue());
}
return self;
}
- (void)enqueueTask:(FIRAuthSerialTask)task {
// This dispatch queue will run tasks serially in FIFO order, as long as it's not suspended.
dispatch_async(self->_dispatchQueue, ^{
// But as soon as a task is started, stop other tasks from running until the task calls it's
// completion handler, which allows the queue to resume processing of tasks. This allows the
// task to perform other asyncronous actions on other dispatch queues and "get back to us" when
// all of their sub-tasks are complete.
dispatch_suspend(self->_dispatchQueue);
task(^{
dispatch_resume(self->_dispatchQueue);
});
});
}
@end
/*
* Copyright 2018 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthSettings.h"
@implementation FIRAuthSettings
- (instancetype)init {
self = [super init];
if (self) {
_appVerificationDisabledForTesting = NO;
}
return self;
}
@end
/*
* Copyright 2018 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRAuthTokenResult_Internal.h"
NS_ASSUME_NONNULL_BEGIN
/** @var kExpirationDateKey
@brief The key used to encode the expirationDate property for NSSecureCoding.
*/
static NSString *const kExpirationDateKey = @"expiratinDate";
/** @var kTokenKey
@brief The key used to encode the token property for NSSecureCoding.
*/
static NSString *const kTokenKey = @"token";
/** @var kAuthDateKey
@brief The key used to encode the authDate property for NSSecureCoding.
*/
static NSString *const kAuthDateKey = @"authDate";
/** @var kIssuedDateKey
@brief The key used to encode the issuedDate property for NSSecureCoding.
*/
static NSString *const kIssuedDateKey = @"issuedDate";
/** @var kSignInProviderKey
@brief The key used to encode the signInProvider property for NSSecureCoding.
*/
static NSString *const kSignInProviderKey = @"signInProvider";
/** @var kClaimsKey
@brief The key used to encode the claims property for NSSecureCoding.
*/
static NSString *const kClaimsKey = @"claims";
@implementation FIRAuthTokenResult
- (instancetype)initWithToken:(NSString *)token
expirationDate:(NSDate *)expirationDate
authDate:(NSDate *)authDate
issuedAtDate:(NSDate *)issuedAtDate
signInProvider:(NSString *)signInProvider
claims:(NSDictionary *)claims {
self = [super init];
if (self) {
_token = token;
_expirationDate = expirationDate;
_authDate = authDate;
_issuedAtDate = issuedAtDate;
_signInProvider = signInProvider;
_claims = claims;
}
return self;
}
#pragma mark - NSSecureCoding
+ (BOOL)supportsSecureCoding {
return YES;
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
NSString *token =
[aDecoder decodeObjectOfClass:[NSDate class] forKey:kTokenKey];
NSDate *expirationDate =
[aDecoder decodeObjectOfClass:[NSDate class] forKey:kExpirationDateKey];
NSDate *authDate =
[aDecoder decodeObjectOfClass:[NSDate class] forKey:kAuthDateKey];
NSDate *issuedAtDate =
[aDecoder decodeObjectOfClass:[NSDate class] forKey:kAuthDateKey];
NSString *signInProvider =
[aDecoder decodeObjectOfClass:[NSString class] forKey:kSignInProviderKey];
NSDictionary<NSString *, NSString *> *claims =
[aDecoder decodeObjectOfClass:[NSDictionary<NSString *, NSString *> class] forKey:kClaimsKey];
return [self initWithToken:token
expirationDate:expirationDate
authDate:authDate
issuedAtDate:issuedAtDate
signInProvider:signInProvider
claims:claims];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_token forKey:kTokenKey];
[aCoder encodeObject:_expirationDate forKey:kExpirationDateKey];
[aCoder encodeObject:_authDate forKey:kAuthDateKey];
[aCoder encodeObject:_issuedAtDate forKey:kIssuedDateKey];
[aCoder encodeObject:_signInProvider forKey:kSignInProviderKey];
[aCoder encodeObject:_claims forKey:kClaimsKey];
}
@end
NS_ASSUME_NONNULL_END
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment