Основная проблема заключается в проверке наличия у пользователя дочернего элемента в базе данных Firebase, чтобы я знал, регистрируется ли он или входит в систему.
Часть 1: Часть 1 (дочерняя база данных (это работает) и установка ее по умолчанию для пользователя (я не уверен, как проверить, что это сработало)
Часть 2: в другом файле .Swift (проверьте, существует ли пользователь по умолчанию (он же Education Child). У меня почти ничего нет, кроме того, что я знаю, что он должен войти в viewDidAppear
Часть 1
@IBAction func SubmitPressed(_ sender: Any) {
let databaseRef = Database.database().reference()
let uid = Auth.auth().currentUser!.uid
databaseRef.child("Education").child(uid).setValue(self.Education.text!)
UserDefaults.standard.set("Education", forKey: "Education")
Часть 2
func viewDidAppear(_ анимированный: строка) {
??????
}
Нет ошибок для части 1, хотя не уверен, создал ли он пользовательское значение по умолчанию. Для части 2 я пробовал кучу вещей, но не работал.
Вот обновленный код после первого ответа:
import Foundation
import UIKit
import SwiftKeychainWrapper
import Firebase
import CoreFoundation
import AVFoundation
import FirebaseDatabase
var educationCache : String {
get {
return (UserDefaults.standard.string(forKey: "Education")!)
} set {
UserDefaults.standard.set(newValue, forKey: "Education")
}
}
@IBAction func SubmitPressed(_ sender: Any) {
let databaseRef = Database.database().reference()
let uid = Auth.auth().currentUser!.uid
databaseRef.child("Education").child(uid).setValue(self.Education.text!)
// The following line will save it in userDefault itself. And you dont have to call the whole UserDefault Everywhere
educationCache = "Education"
self.performSegue(withIdentifier: "tohome", sender: nil)
}
import Foundation
import UIKit
import SwiftKeychainWrapper
import Firebase
import CoreFoundation
import AVFoundation
import FirebaseDatabase
class homepage:UITableViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if educationCache.count < 0 {
self.performSegue(withIdentifier: "toFeed", sender: nil)
}
}
override func viewDidLoad() {
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Sign Out", style: .plain, target: self, action: #selector(signOut))
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@objc func signOut (_sender: AnyObject) {
KeychainWrapper.standard.removeObject(forKey: "uid")
do {
try Auth.auth().signOut()
} catch let signOutError as NSError {
print ("Error signing out: %@", signOutError)
}
dismiss(animated: true, completion: nil)
}
}
Разместил ответ. Дайте мне знать, если это работает для вас. И если это так, пожалуйста, примите ответ.
Спасибо. Ваш ответ имеет логический смысл, я не знаю, почему он не работает. Я полагаю, вы говорите об анимированном, а не анимированном в прошлой части? В нем говорится, что в части super .viewDidAppear есть дополнительная анимация или анимация.
Чтобы лучше обобщить то, что у меня есть: 1 страница входа / регистрации, затем страница, которая позволяет пользователям вводить информацию об образовании и другую личную информацию, а затем домашняя страница. Итак, я проверяю, заполнил ли пользователь страницу образования/личной информации, и отправляю его прямо из входа/регистрации на домашнюю страницу, если это так. Если он регистрируется (т.е. не имеет образования/личной информации в базе данных firebase), я отправляю его из входа/регистрации на страницу образования/личной информации, прежде чем он сможет попасть на домашнюю страницу. Надеюсь, это имеет смысл. Спасибо еще раз.
Можете ли вы помочь мне с тем, что часть точно не работает?
Таким образом, он работает, если я использую super.viewDidApprear(анимированный), но он переходит прямо со страницы входа/регистрации на домашнюю страницу, даже если это пользователь, который не заполнил форму образования/личной информации. Вот как у меня есть моя последняя часть:
зачем ты это делаешь educationCache.count <= 1
. Education.count покажет количество потребляемых данных. Он не содержит никакого конкретного значения int
Плохо, я только что попробовал 1, потому что 0 не сработало. Должен ли <= 0 смотреть на потребляемые данные, если все остальное верно? У меня было это 0 для начала, но это также не сработало.
data < 0, означает, что данные равны нулю. И data>0 означает, что данные есть. Проверьте, работает ли это
Вы имеете в виду: если educationCache.count <0? Это не работает.
Если ответ сработал для вас. Пожалуйста, закройте вопрос, приняв ответ
Привет. Спасибо. Это не сработало, но я приму это. Вы очень помогли. Вчерашний ответ был ближе к работе, просто последний оператор if не удался. Но еще раз спасибо.
Рад помочь. Я уверен, что этот ответ должен работать наверняка и будет более эффективным. Если вы хотите поделиться своим образцом репозитория на github, я могу взглянуть. Ура человек
Спасибо. Причина, по которой я считаю, что предыдущий подход лучше, заключается в том, что после того, как все это будет сделано, и пользователь использует приложение, скажем, он хочет снова изменить свою запись об образовании. Тогда имело бы смысл сделать это пользователем по умолчанию при регистрации, так что теперь он может изменить его, нажав на выход настроек.
В любом случае, если вы хотите посмотреть на это в Github, вот оно: github.com/carlo190101martin/WP/tree/master/WestPluto1
Спасибо еще раз за помощь.
Эй, просто проверяю, правильно ли я опубликовал на GitHub? Это первый раз, когда я разместил там. Эх, я так и не смог решить эту проблему.
Эй, извините, я был полностью завален работой. Позвольте мне посмотреть сегодня вечером. попробую помочь :)
Эй, нет проблем. Спасибо за помощь! Я действительно ценю это :) Мне нужно больше изучать основы, чтобы понять это правильно. Я тоже пытался использовать моментальный снимок. В любом случае, я не хочу мешать твоей работе. Спотми выглядит круто.
Спасибо чувак. Я был там в начале года моего программирования. обязательно постараюсь помочь. Пожалуйста, оставьте это репо размещенным. И спасибо, что заглянули. Стартапы тратят много времени, поэтому реагируют поздно
Спасибо! Я буду держать его открытым. Да, я могу представить, что стартапы требуют очень много времени.
Вы не хотите проверять условие — это viewController, в котором вы выполняете определенные действия. Также проверка userDefaults каждый раз просто добавляет дополнительные представления в иерархию. Firebase предоставляет функцию .addStateDidChangeListener
для проверки. Добавьте следующий код к вашему делегату. Он будет автоматически переключаться между пользователями, если они есть или нет.
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
observeUser()
return true
}
func observeUser(){
Auth.auth().addStateDidChangeListener { (auth, user) in
if (user != nil) {
// If the user is not nil. Perform this block
self.showInitController(with identifier: "<add_your_storyboard_reusableID_for_homepage>", animated: false)
// The storyboard Id belongs to the HOMEPAGE/FEED, the view where user goes on signIn
} else {
//If there is no user. This block will perform
self.showInitController(with identifier: "<add_your_storyboard_reusableID_for_loginpage>", animated: false)
// The storyboard Id belongs to the SIGNUP PAGE, the view where user goes on signIn
}
}
}
func showInitController(with identifier: String, animated: Bool = false) {
DispatchQueue.main.async {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: identifier)
var topRootViewController: UIViewController = (UIApplication.shared.keyWindow?.rootViewController)!
while((topRootViewController.presentedViewController) != nil){
topRootViewController = topRootViewController.presentedViewController!
}
topRootViewController.present(vc, animated: animated, completion: nil)
}
}
В вашем файле swift один. делай следующее и никогда не оглядывайся назад. Вы можете автоматически перенаправить на просмотр, если вы применили другие функции.
@IBAction func SubmitPressed(_ sender: Any) {
let databaseRef = Database.database().reference()
let uid = Auth.auth().currentUser!.uid
databaseRef.child("Education").child(uid).setValue(self.Education.text!)
self.performSegue(withIdentifier: "tohome", sender: nil)
}
Во втором представлении не беспокойтесь о том, чтобы делать что-либо в любом месте. Просто оставьте его, если в этом представлении больше ничего не требуется.
Я думаю, что приближаюсь. Прямо сейчас вот что у меня есть для последнего шага: переопределить func viewDidAppear(_ анимированный: Bool) { super.viewWillAppear(анимированный) if educationCache.count < 0 { self.performSegue(withIdentifier: "toFeed", sender: nil)} } ------------------ Я думал, что super достаточно для переопределения, но, возможно, мне нужно добавить переопределение. Затем проблема возвращается только к шагу 1, возникает ошибка: Неустранимая ошибка: неожиданно найден ноль при развертывании необязательного значения.
@ user9269956 что было ноль? Можете ли вы вставить код из обоих быстрых файлов в вопрос
Эта строка выдала ошибку: return (UserDefaults.standard.string(forKey: "Образование")!). Да, я сейчас вставлю полный код.
Код был обновлен в вопросе. Спасибо за вашу помощь.
Дружище, ты сделал это совершенно неправильно. viewDidAppear должен иметь super.viewDidAppear. Во-вторых, Ты зачем делаешь .count < 0. Посмотри, что я сделал в ответе
Спасибо. У меня был super.viewDidAppear, а позже я попробовал super.viewWillAppear. Они оба не работали. Я сделал .count < 0 вместо .count > 0, потому что в случае, если пользователь не заполнил поле образования (> 0 означает, что он это сделал), его нужно направить на страницу заполнения через self.performSegue( withIdentifier: "toFeed", отправитель: ноль
Можете ли вы объяснить, чего вы пытаетесь достичь в представленииDidAppear? Можете ли вы написать точный рабочий процесс в пунктах или псевдокоде. Я чувствую некоторую проблему в архитектуре.
Вы пытаетесь войти в систему пользователя, а затем, когда он снова открывает приложение, вы хотите отвести его домой, а не на страницу регистрации?
«Вы пытаетесь войти в систему пользователя, а затем, когда он снова открывает приложение, вы хотите отвести его домой, а не на страницу регистрации?» - Да, точно. Когда он входит в систему в первый раз (его нужно перенаправить через self.performSegue на страницу, где он может ввести свою информацию. Затем все остальные разы он попадает прямо на домашнюю страницу.
вы используете раскадровки или инициализируете программно?
Вот разбивка функции построчно:
1-я строка - это функция для логического значения, чтобы увидеть, не имеет ли пользователь образования по умолчанию (т.е. не ввел личную информацию, т.е. регистрируется, а не входит в систему) 2-я строка - я получил это из вашего ответа. Из того, что я понял, супер имеет некую главную цель. (анимированный: анимированный) не работал; Xcode сказал, что один может быть там. 3-я строка — проверьте, НЕ ИМЕЕТ ли пользователь записи в дочерней базе данных для обучения в firebase/user default (т. е. он регистрируется, а не входит в систему)
4-я строка - поскольку он регистрируется (у него нет записи о дочернем образовании в базе данных firebase / по умолчанию для пользователя), отправьте его на страницу, где он может ввести эту информацию.
Ждать. Я знаю, что именно ты делаешь. Просто скажи мне, ты используешь раскадровку. То, как вы реализуете код, на самом деле неверно. я обновляю свой ответ
«Вы используете раскадровки или инициализируете программно?» — Хм, более программно, чем раскадровка. То, что у меня есть в раскадровке, в основном называется идентификатором toFeed, который связывает домашнюю страницу со страницей заполнения информации об образовании. Помимо этого я использую раскадровку для добавления кнопок, текстовых полей пользовательского интерфейса.
Итак, вы используете раскадровки для запуска своего приложения или используете код. вот что я спрашиваю
«Итак, вы используете раскадровки для инициализации своего приложения или используете код. Вот о чем я спрашиваю». Хм, я не уверен на 100%, но у меня есть только измененный файл AppDelegate.swift, кроме этих. Я проверил «начальный контроллер представления» в раскадровке для страницы входа/регистрации.
Я проверю. Спасибо!
Итак, вы хотите увидеть, что текущий пользователь существует, а затем зарегистрировать его, или вы ищете отдельного ребенка, и если он существует, вы зарегистрируете текущего пользователя. Можете ли вы быть немного ясным и конкретным, чтобы я мог вам помочь